summaryrefslogtreecommitdiffstats
path: root/components/json_schema
diff options
context:
space:
mode:
authorjoaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-08 22:23:46 +0000
committerjoaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-08 22:23:46 +0000
commit200799c3b53491d58480edcc82cc332dd5362e1b (patch)
treedc44442df2f116574e3336288d24c6365e2147e3 /components/json_schema
parenta3cdef6c97123dd2f18697ffda40df6f9bdf5ad4 (diff)
downloadchromium_src-200799c3b53491d58480edcc82cc332dd5362e1b.zip
chromium_src-200799c3b53491d58480edcc82cc332dd5362e1b.tar.gz
chromium_src-200799c3b53491d58480edcc82cc332dd5362e1b.tar.bz2
Ignore unknown attributes when parsing JSON schemas.
JSON schemas are used by extensions that support enterprise management, to declare the policies that they support. The current parser rejects schemas with unknown attributes; this CL lifts that restriction for 2 reasons: - the JSON schema spec does not mandate this behavior for validators - it restricts future extensions to this format BUG=108992 Review URL: https://codereview.chromium.org/94043003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@239407 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components/json_schema')
-rw-r--r--components/json_schema/json_schema_validator.cc31
-rw-r--r--components/json_schema/json_schema_validator.h13
-rw-r--r--components/json_schema/json_schema_validator_unittest.cc15
3 files changed, 48 insertions, 11 deletions
diff --git a/components/json_schema/json_schema_validator.cc b/components/json_schema/json_schema_validator.cc
index 32cb93c..310975a 100644
--- a/components/json_schema/json_schema_validator.cc
+++ b/components/json_schema/json_schema_validator.cc
@@ -65,7 +65,9 @@ const base::Value* ExtractNameFromDictionary(const base::Value* value) {
return value;
}
-bool IsValidSchema(const base::DictionaryValue* dict, std::string* error) {
+bool IsValidSchema(const base::DictionaryValue* dict,
+ int options,
+ std::string* error) {
// This array must be sorted, so that std::lower_bound can perform a
// binary search.
static const ExpectedType kExpectedTypes[] = {
@@ -126,7 +128,7 @@ bool IsValidSchema(const base::DictionaryValue* dict, std::string* error) {
// Validate the "items" attribute, which is a schema or a list of schemas.
if (it.key() == schema::kItems) {
if (it.value().GetAsDictionary(&dictionary_value)) {
- if (!IsValidSchema(dictionary_value, error)) {
+ if (!IsValidSchema(dictionary_value, options, error)) {
DCHECK(!error->empty());
return false;
}
@@ -138,7 +140,7 @@ bool IsValidSchema(const base::DictionaryValue* dict, std::string* error) {
static_cast<int>(i));
return false;
}
- if (!IsValidSchema(dictionary_value, error)) {
+ if (!IsValidSchema(dictionary_value, options, error)) {
DCHECK(!error->empty());
return false;
}
@@ -155,9 +157,12 @@ bool IsValidSchema(const base::DictionaryValue* dict, std::string* error) {
const ExpectedType* entry = std::lower_bound(
kExpectedTypes, end, it.key(), CompareToString);
if (entry == end || entry->key != it.key()) {
+ if (options & JSONSchemaValidator::OPTIONS_IGNORE_UNKNOWN_ATTRIBUTES)
+ continue;
*error = base::StringPrintf("Invalid attribute %s", it.key().c_str());
return false;
}
+
if (!it.value().IsType(entry->type)) {
*error = base::StringPrintf("Invalid value for %s attribute",
it.key().c_str());
@@ -185,7 +190,7 @@ bool IsValidSchema(const base::DictionaryValue* dict, std::string* error) {
*error = "Invalid value for properties attribute";
return false;
}
- if (!IsValidSchema(dictionary_value, error)) {
+ if (!IsValidSchema(dictionary_value, options, error)) {
DCHECK(!error->empty());
return false;
}
@@ -195,7 +200,7 @@ bool IsValidSchema(const base::DictionaryValue* dict, std::string* error) {
// Validate "additionalProperties" attribute, which is a schema.
if (it.key() == schema::kAdditionalProperties) {
it.value().GetAsDictionary(&dictionary_value);
- if (!IsValidSchema(dictionary_value, error)) {
+ if (!IsValidSchema(dictionary_value, options, error)) {
DCHECK(!error->empty());
return false;
}
@@ -236,7 +241,7 @@ bool IsValidSchema(const base::DictionaryValue* dict, std::string* error) {
*error = "Invalid choices attribute";
return false;
}
- if (!IsValidSchema(dictionary_value, error)) {
+ if (!IsValidSchema(dictionary_value, options, error)) {
DCHECK(!error->empty());
return false;
}
@@ -356,9 +361,17 @@ std::string JSONSchemaValidator::FormatErrorMessage(const std::string& format,
scoped_ptr<base::DictionaryValue> JSONSchemaValidator::IsValidSchema(
const std::string& schema,
std::string* error) {
- base::JSONParserOptions options = base::JSON_PARSE_RFC;
+ return JSONSchemaValidator::IsValidSchema(schema, 0, error);
+}
+
+// static
+scoped_ptr<base::DictionaryValue> JSONSchemaValidator::IsValidSchema(
+ const std::string& schema,
+ int validator_options,
+ std::string* error) {
+ base::JSONParserOptions json_options = base::JSON_PARSE_RFC;
scoped_ptr<base::Value> json(
- base::JSONReader::ReadAndReturnError(schema, options, NULL, error));
+ base::JSONReader::ReadAndReturnError(schema, json_options, NULL, error));
if (!json)
return scoped_ptr<base::DictionaryValue>();
base::DictionaryValue* dict = NULL;
@@ -366,7 +379,7 @@ scoped_ptr<base::DictionaryValue> JSONSchemaValidator::IsValidSchema(
*error = "Schema must be a JSON object";
return scoped_ptr<base::DictionaryValue>();
}
- if (!::IsValidSchema(dict, error))
+ if (!::IsValidSchema(dict, validator_options, error))
return scoped_ptr<base::DictionaryValue>();
ignore_result(json.release());
return make_scoped_ptr(dict);
diff --git a/components/json_schema/json_schema_validator.h b/components/json_schema/json_schema_validator.h
index 4584a9d..4e8acad 100644
--- a/components/json_schema/json_schema_validator.h
+++ b/components/json_schema/json_schema_validator.h
@@ -70,6 +70,12 @@ class JSONSchemaValidator {
std::string message;
};
+ enum Options {
+ // Ignore unknown attributes. If this option is not set then unknown
+ // attributes will make the schema validation fail.
+ OPTIONS_IGNORE_UNKNOWN_ATTRIBUTES = 1 << 0,
+ };
+
// Error messages.
static const char kUnknownTypeReference[];
static const char kInvalidChoice[];
@@ -108,6 +114,13 @@ class JSONSchemaValidator {
const std::string& schema,
std::string* error);
+ // Same as above but with |options|, which is a bitwise-OR combination of the
+ // Options above.
+ static scoped_ptr<base::DictionaryValue> IsValidSchema(
+ const std::string& schema,
+ int options,
+ std::string* error);
+
// Creates a validator for the specified schema.
//
// NOTE: This constructor assumes that |schema| is well formed and valid.
diff --git a/components/json_schema/json_schema_validator_unittest.cc b/components/json_schema/json_schema_validator_unittest.cc
index 6372032..73809de 100644
--- a/components/json_schema/json_schema_validator_unittest.cc
+++ b/components/json_schema/json_schema_validator_unittest.cc
@@ -83,8 +83,7 @@ TEST(JSONSchemaValidator, IsValidSchema) {
"{"
" \"type\": \"string\","
" \"enum\": [ { \"name\": {} } ]" // "enum" name must be a simple value.
- "}",
- &error));
+ "}", &error));
EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
"{"
" \"type\": \"array\","
@@ -132,4 +131,16 @@ TEST(JSONSchemaValidator, IsValidSchema) {
" \"type\": \"any\""
" }"
"}", &error)) << error;
+ EXPECT_TRUE(JSONSchemaValidator::IsValidSchema(
+ "{"
+ " \"type\": \"object\","
+ " \"unknown attribute\": \"that should just be ignored\""
+ "}",
+ JSONSchemaValidator::OPTIONS_IGNORE_UNKNOWN_ATTRIBUTES,
+ &error)) << error;
+ EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
+ "{"
+ " \"type\": \"object\","
+ " \"unknown attribute\": \"that will cause a failure\""
+ "}", 0, &error)) << error;
}