Index: components/policy/core/common/schema.cc |
diff --git a/components/policy/core/common/schema.cc b/components/policy/core/common/schema.cc |
index 18891a662866e319d3bb9849759cc35bb73f5fba..29722965d7b0fb71c6117f8b79e347057a1bd6f0 100644 |
--- a/components/policy/core/common/schema.cc |
+++ b/components/policy/core/common/schema.cc |
@@ -13,6 +13,7 @@ |
#include "base/compiler_specific.h" |
#include "base/logging.h" |
#include "base/memory/scoped_vector.h" |
+#include "base/strings/stringprintf.h" |
#include "components/json_schema/json_schema_constants.h" |
#include "components/json_schema/json_schema_validator.h" |
#include "components/policy/core/common/schema_internal.h" |
@@ -104,6 +105,31 @@ SchemaOnErrorStrategy StrategyForNextLevel(SchemaOnErrorStrategy strategy) { |
return next_level_strategy[(int)strategy]; |
} |
+void SchemaFindError(std::string* error_path,std::string *error, |
Joao da Silva
2014/01/23 20:59:31
A better name for this is ErrorFound
binjin
2014/01/23 21:21:58
Done.
|
+ const std::string& msg) { |
Joao da Silva
2014/01/23 20:59:31
Format this. One argument per line:
void SchemaFi
binjin
2014/01/23 21:21:58
Done.
|
+ if (error_path) |
+ *error_path = ""; |
+ *error = msg; |
+} |
+ |
+void AddListIndexPrefixToPath(int index, std::string* path) { |
+ if (path) { |
+ if (path->size() == 0) |
Joao da Silva
2014/01/23 20:59:31
path->empty
binjin
2014/01/23 21:21:58
Done.
|
+ *path = base::StringPrintf("items[%d]", index); |
+ else |
+ *path = base::StringPrintf("items[%d].", index) + *path; |
Joao da Silva
2014/01/23 20:59:31
Maybe just "[%d]" without the "items" looks OK?
E
binjin
2014/01/23 21:21:58
root schema can be a list, and things like "[4].fi
|
+ } |
+} |
+ |
+void AddDictKeyPrefixToPath(const std::string& key, std::string* path) { |
+ if (path) { |
+ if (path->size() == 0) |
Joao da Silva
2014/01/23 20:59:31
path->empty
binjin
2014/01/23 21:21:58
Done.
|
+ *path = key; |
+ else |
+ *path = key + "." + *path; |
+ } |
+} |
+ |
} // namespace |
// Contains the internal data representation of a Schema. This can either wrap |
@@ -633,9 +659,10 @@ Schema Schema::Wrap(const SchemaData* data) { |
bool Schema::Validate(const base::Value& value, |
SchemaOnErrorStrategy strategy, |
+ std::string* error_path, |
std::string* error) const { |
if (!valid()) { |
- *error = "The schema is invalid."; |
+ SchemaFindError(error_path, error, "The schema is invalid."); |
return false; |
} |
@@ -646,7 +673,8 @@ bool Schema::Validate(const base::Value& value, |
type() == base::Value::TYPE_DOUBLE) |
return true; |
- *error = "The value type doesn't match the schema type."; |
+ SchemaFindError(error_path, error, |
+ "The value type doesn't match the schema type."); |
Joao da Silva
2014/01/23 20:59:31
Format this line.
binjin
2014/01/23 21:21:58
Done.
|
return false; |
} |
@@ -660,28 +688,25 @@ bool Schema::Validate(const base::Value& value, |
Schema subschema = GetProperty(it.key()); |
if (!subschema.valid()) { |
// Unknown property was detected. |
- if (!StrategyAllowUnknownOnTopLevel(strategy)) { |
- *error = "Unknown property: " + it.key(); |
+ SchemaFindError(error_path, error, "Unknown property: " + it.key()); |
+ if (!StrategyAllowUnknownOnTopLevel(strategy)) |
+ return false; |
+ } else if (!subschema.Validate(it.value(), |
+ StrategyForNextLevel(strategy), error_path, error)) { |
Joao da Silva
2014/01/23 20:59:31
Format this line
binjin
2014/01/23 21:21:58
Done.
|
+ // Invalid property was detected. |
+ AddDictKeyPrefixToPath(it.key(), error_path); |
+ if (!StrategyAllowInvalidOnTopLevel(strategy)) |
return false; |
- } |
- } else { |
- std::string sub_error; |
- if (!subschema.Validate( |
- it.value(), StrategyForNextLevel(strategy), &sub_error)) { |
- // Invalid property was detected. |
- if (!StrategyAllowInvalidOnTopLevel(strategy)) { |
- *error = sub_error; |
- return false; |
- } |
- } |
} |
} |
} else if (value.GetAsList(&list)) { |
for (base::ListValue::const_iterator it = list->begin(); it != list->end(); |
++it) { |
if (!*it || |
- !GetItems().Validate(**it, StrategyForNextLevel(strategy), error)) { |
+ !GetItems().Validate( |
+ **it, StrategyForNextLevel(strategy), error_path, error)) { |
// Invalid list item was detected. |
+ AddListIndexPrefixToPath(it - list->begin(), error_path); |
if (!StrategyAllowInvalidOnTopLevel(strategy)) |
return false; |
} |
@@ -689,13 +714,13 @@ bool Schema::Validate(const base::Value& value, |
} else if (value.GetAsInteger(&int_value)) { |
if (node_->extra != kInvalid && |
!ValidateIntegerRestriction(node_->extra, int_value)) { |
- *error = "Invalid value for integer"; |
+ SchemaFindError(error_path, error, "Invalid value for integer"); |
return false; |
} |
} else if (value.GetAsString(&str_value)) { |
if (node_->extra != kInvalid && |
!ValidateStringRestriction(node_->extra, str_value.c_str())) { |
- *error = "Invalid value for string"; |
+ SchemaFindError(error_path, error, "Invalid value for string"); |
return false; |
} |
} |
@@ -705,9 +730,10 @@ bool Schema::Validate(const base::Value& value, |
bool Schema::Normalize(base::Value* value, |
SchemaOnErrorStrategy strategy, |
+ std::string* error_path, |
std::string* error) const { |
if (!valid()) { |
- *error = "The schema is invalid."; |
+ SchemaFindError(error_path, error, "The schema is invalid."); |
return false; |
} |
@@ -719,7 +745,8 @@ bool Schema::Normalize(base::Value* value, |
type() == base::Value::TYPE_DOUBLE) |
return true; |
- *error = "The value type doesn't match the schema type."; |
+ SchemaFindError(error_path, error, |
+ "The value type doesn't match the schema type."); |
Joao da Silva
2014/01/23 20:59:31
Format this line
binjin
2014/01/23 21:21:58
Done.
|
return false; |
} |
@@ -732,25 +759,24 @@ bool Schema::Normalize(base::Value* value, |
Schema subschema = GetProperty(it.key()); |
if (!subschema.valid()) { |
// Unknown property was detected. |
- if (StrategyAllowUnknownOnTopLevel(strategy)) { |
+ SchemaFindError(error_path, error, "Unknown property: " + it.key()); |
+ if (StrategyAllowUnknownOnTopLevel(strategy)) |
drop_list.push_back(it.key()); |
- } else { |
- *error = "Unknown property: " + it.key(); |
+ else |
return false; |
- } |
} else { |
base::Value* sub_value = NULL; |
dict->GetWithoutPathExpansion(it.key(), &sub_value); |
- std::string sub_error; |
- if (!subschema.Normalize( |
- sub_value, StrategyForNextLevel(strategy), &sub_error)) { |
+ if (!subschema.Normalize(sub_value, |
+ StrategyForNextLevel(strategy), |
+ error_path, |
+ error)) { |
// Invalid property was detected. |
- if (StrategyAllowInvalidOnTopLevel(strategy)) { |
+ AddDictKeyPrefixToPath(it.key(), error_path); |
+ if (StrategyAllowInvalidOnTopLevel(strategy)) |
drop_list.push_back(it.key()); |
- } else { |
- *error = sub_error; |
+ else |
return false; |
- } |
} |
} |
} |
@@ -764,18 +790,16 @@ bool Schema::Normalize(base::Value* value, |
std::vector<size_t> drop_list; // Contains the indexes to drop. |
for (size_t index = 0; index < list->GetSize(); index++) { |
base::Value* sub_value = NULL; |
- std::string sub_error; |
list->Get(index, &sub_value); |
if (!sub_value || |
!GetItems().Normalize( |
- sub_value, StrategyForNextLevel(strategy), &sub_error)) { |
+ sub_value, StrategyForNextLevel(strategy), error_path, error)) { |
// Invalid list item was detected. |
- if (StrategyAllowInvalidOnTopLevel(strategy)) { |
+ AddListIndexPrefixToPath(index, error_path); |
+ if (StrategyAllowInvalidOnTopLevel(strategy)) |
drop_list.push_back(index); |
- } else { |
- *error = sub_error; |
+ else |
return false; |
- } |
} |
} |
for (std::vector<size_t>::reverse_iterator it = drop_list.rbegin(); |
@@ -785,7 +809,7 @@ bool Schema::Normalize(base::Value* value, |
return true; |
} |
- return Validate(*value, strategy, error); |
+ return Validate(*value, strategy, error_path, error); |
} |
// static |
@@ -890,7 +914,7 @@ bool Schema::ValidateIntegerRestriction(int index, int value) const { |
} |
} |
-bool Schema::ValidateStringRestriction(int index, const char *str) const { |
+bool Schema::ValidateStringRestriction(int index, const char* str) const { |
const RestrictionNode* rnode = storage_->restriction(index); |
for (int i = rnode->enumeration_restriction.offset_begin; |
i < rnode->enumeration_restriction.offset_end; i++) { |