buffet: PropType::CreateValue() should do constraint validation Make PropType::CreateValue(v,...) validate the value against type contraints which eliminates additional ValidateConstraints() call and ensure the produced values conforms to the type schema specified. Also parameter-less PropType::CreateValue() should use the default value specified in PropType when constructing the value. BUG=brillo:107 TEST=`FEATURES=test emerge-link buffet` Change-Id: I3712b8e0a14515c153c987078863b2904c89cafd Reviewed-on: https://chromium-review.googlesource.com/262205 Reviewed-by: Vitaly Buka <vitalybuka@chromium.org> Commit-Queue: Alex Vakulenko <avakulenko@chromium.org> Tested-by: Alex Vakulenko <avakulenko@chromium.org> Trybot-Ready: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/commands/prop_types.cc b/buffet/commands/prop_types.cc index a31f135..74e2be6 100644 --- a/buffet/commands/prop_types.cc +++ b/buffet/commands/prop_types.cc
@@ -211,8 +211,7 @@ bool PropType::ValidateValue(const chromeos::Any& value, chromeos::ErrorPtr* error) const { - std::unique_ptr<PropValue> val = CreateValue(value, error); - return val && ValidateConstraints(*val, error); + return !!CreateValue(value, error); } bool PropType::ValidateConstraints(const PropValue& value,
diff --git a/buffet/commands/prop_types.h b/buffet/commands/prop_types.h index 10ca853..473a6c8 100644 --- a/buffet/commands/prop_types.h +++ b/buffet/commands/prop_types.h
@@ -186,6 +186,8 @@ public: ValueType GetType() const override { return GetValueType<T>(); } std::unique_ptr<PropValue> CreateValue() const override { + if (GetDefaultValue()) + return GetDefaultValue()->Clone(); return std::unique_ptr<PropValue>{new Value{Clone()}}; } std::unique_ptr<PropValue> CreateValue( @@ -194,7 +196,8 @@ if (v.IsTypeCompatible<T>()) { std::unique_ptr<Value> value{new Value{Clone()}}; value->SetValue(v.Get<T>()); - prop_value = std::move(value); + if (ValidateConstraints(*value, error)) + prop_value = std::move(value); } else { GenerateErrorValueTypeMismatch(error); }
diff --git a/buffet/commands/schema_utils.cc b/buffet/commands/schema_utils.cc index 10e9797..06e5ded 100644 --- a/buffet/commands/schema_utils.cc +++ b/buffet/commands/schema_utils.cc
@@ -138,6 +138,7 @@ const ObjectSchema* object_schema = type->GetObject()->GetObjectSchemaPtr(); std::set<std::string> keys_processed; + value_out->clear(); // Clear possible default values already in |value_out|. for (const auto& pair : object_schema->GetProps()) { const PropValue* def_value = pair.second->GetDefaultValue(); if (dict->HasKey(pair.first)) { @@ -154,9 +155,9 @@ pair.first.c_str()); return false; } - value_out->insert(std::make_pair(pair.first, std::move(value))); + value_out->emplace_hint(value_out->end(), pair.first, std::move(value)); } else if (def_value) { - value_out->insert(std::make_pair(pair.first, def_value->Clone())); + value_out->emplace_hint(value_out->end(), pair.first, def_value->Clone()); } else { return ErrorMissingProperty(error, pair.first.c_str()); } @@ -207,6 +208,9 @@ const PropType* item_type = type->GetArray()->GetItemTypePtr(); CHECK(item_type) << "Incomplete array type definition"; + // This value might already contain values from the type defaults. + // Clear them first before proceeding. + value_out->clear(); value_out->reserve(list->GetSize()); for (const base::Value* item : *list) { std::unique_ptr<PropValue> prop_value = item_type->CreateValue(); @@ -309,8 +313,6 @@ result = type->CreateValue(value, error); } - if (result && !type->ValidateConstraints(*result, error)) - result.reset(); return result; } @@ -319,6 +321,7 @@ native_types::Object* obj, chromeos::ErrorPtr* error) { std::set<std::string> keys_processed; + obj->clear(); // First go over all object parameters defined by type's object schema and // extract the corresponding parameters from the source dictionary. for (const auto& pair : object_schema->GetProps()) {
diff --git a/buffet/states/state_package.cc b/buffet/states/state_package.cc index a023c14..1292339 100644 --- a/buffet/states/state_package.cc +++ b/buffet/states/state_package.cc
@@ -39,11 +39,7 @@ for (const auto& pair : schema.GetProps()) { types_.AddProp(pair.first, pair.second->Clone()); // Create default value for this state property. - if (pair.second->GetDefaultValue()) { - values_.emplace(pair.first, pair.second->GetDefaultValue()->Clone()); - } else { - values_.emplace(pair.first, pair.second->CreateValue()); - } + values_.emplace(pair.first, pair.second->CreateValue()); } return true;