OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/json_schema/json_schema_validator.h" | 5 #include "components/json_schema/json_schema_validator.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cfloat> | 8 #include <cfloat> |
9 #include <cmath> | 9 #include <cmath> |
10 | 10 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 struct ExpectedType { | 46 struct ExpectedType { |
47 const char* key; | 47 const char* key; |
48 base::Value::Type type; | 48 base::Value::Type type; |
49 }; | 49 }; |
50 | 50 |
51 // Helper for std::lower_bound. | 51 // Helper for std::lower_bound. |
52 bool CompareToString(const ExpectedType& entry, const std::string& key) { | 52 bool CompareToString(const ExpectedType& entry, const std::string& key) { |
53 return entry.key < key; | 53 return entry.key < key; |
54 } | 54 } |
55 | 55 |
56 // If |value| is a dictionary, returns the "name" attribute of |value| or NULL | |
57 // if |value| does not contain a "name" attribute. Otherwise, returns |value|. | |
58 const base::Value* ExtractNameFromDictionary(const base::Value* value) { | |
59 const base::DictionaryValue* value_dict = NULL; | |
60 const base::Value* name_value = NULL; | |
61 if (value->GetAsDictionary(&value_dict)) { | |
62 value_dict->Get("name", &name_value); | |
63 return name_value; | |
64 } | |
65 return value; | |
66 } | |
67 | |
68 bool IsValidSchema(const base::DictionaryValue* dict, std::string* error) { | 56 bool IsValidSchema(const base::DictionaryValue* dict, std::string* error) { |
69 // This array must be sorted, so that std::lower_bound can perform a | 57 // This array must be sorted, so that std::lower_bound can perform a |
70 // binary search. | 58 // binary search. |
71 static const ExpectedType kExpectedTypes[] = { | 59 static const ExpectedType kExpectedTypes[] = { |
72 // Note: kRef == "$ref", kSchema == "$schema" | 60 // Note: kRef == "$ref", kSchema == "$schema" |
73 { schema::kRef, base::Value::TYPE_STRING }, | 61 { schema::kRef, base::Value::TYPE_STRING }, |
74 { schema::kSchema, base::Value::TYPE_STRING }, | 62 { schema::kSchema, base::Value::TYPE_STRING }, |
75 | 63 |
76 { schema::kAdditionalProperties, base::Value::TYPE_DICTIONARY }, | 64 { schema::kAdditionalProperties, base::Value::TYPE_DICTIONARY }, |
77 { schema::kChoices, base::Value::TYPE_LIST }, | 65 { schema::kChoices, base::Value::TYPE_LIST }, |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 return false; | 188 return false; |
201 } | 189 } |
202 } | 190 } |
203 | 191 |
204 // Validate the values contained in an "enum" attribute. | 192 // Validate the values contained in an "enum" attribute. |
205 if (it.key() == schema::kEnum) { | 193 if (it.key() == schema::kEnum) { |
206 it.value().GetAsList(&list_value); | 194 it.value().GetAsList(&list_value); |
207 for (size_t i = 0; i < list_value->GetSize(); ++i) { | 195 for (size_t i = 0; i < list_value->GetSize(); ++i) { |
208 const base::Value* value = NULL; | 196 const base::Value* value = NULL; |
209 list_value->Get(i, &value); | 197 list_value->Get(i, &value); |
210 // Sometimes the enum declaration is a dictionary with the enum value | |
211 // under "name". | |
212 value = ExtractNameFromDictionary(value); | |
213 if (!value) { | |
214 *error = "Invalid value in enum attribute"; | |
215 return false; | |
216 } | |
217 switch (value->GetType()) { | 198 switch (value->GetType()) { |
218 case base::Value::TYPE_NULL: | 199 case base::Value::TYPE_NULL: |
219 case base::Value::TYPE_BOOLEAN: | 200 case base::Value::TYPE_BOOLEAN: |
220 case base::Value::TYPE_INTEGER: | 201 case base::Value::TYPE_INTEGER: |
221 case base::Value::TYPE_DOUBLE: | 202 case base::Value::TYPE_DOUBLE: |
222 case base::Value::TYPE_STRING: | 203 case base::Value::TYPE_STRING: |
223 break; | 204 break; |
224 default: | 205 default: |
225 *error = "Invalid value in enum attribute"; | 206 *error = "Invalid value in enum attribute"; |
226 return false; | 207 return false; |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 errors_.push_back(Error(path, kInvalidChoice)); | 472 errors_.push_back(Error(path, kInvalidChoice)); |
492 return; | 473 return; |
493 } | 474 } |
494 | 475 |
495 void JSONSchemaValidator::ValidateEnum(const base::Value* instance, | 476 void JSONSchemaValidator::ValidateEnum(const base::Value* instance, |
496 const base::ListValue* choices, | 477 const base::ListValue* choices, |
497 const std::string& path) { | 478 const std::string& path) { |
498 for (size_t i = 0; i < choices->GetSize(); ++i) { | 479 for (size_t i = 0; i < choices->GetSize(); ++i) { |
499 const base::Value* choice = NULL; | 480 const base::Value* choice = NULL; |
500 CHECK(choices->Get(i, &choice)); | 481 CHECK(choices->Get(i, &choice)); |
501 // Sometimes the enum declaration is a dictionary with the enum value under | |
502 // "name". | |
503 choice = ExtractNameFromDictionary(choice); | |
504 if (!choice) { | |
505 NOTREACHED(); | |
506 } | |
507 switch (choice->GetType()) { | 482 switch (choice->GetType()) { |
508 case base::Value::TYPE_NULL: | 483 case base::Value::TYPE_NULL: |
509 case base::Value::TYPE_BOOLEAN: | 484 case base::Value::TYPE_BOOLEAN: |
510 case base::Value::TYPE_STRING: | 485 case base::Value::TYPE_STRING: |
511 if (instance->Equals(choice)) | 486 if (instance->Equals(choice)) |
512 return; | 487 return; |
513 break; | 488 break; |
514 | 489 |
515 case base::Value::TYPE_INTEGER: | 490 case base::Value::TYPE_INTEGER: |
516 case base::Value::TYPE_DOUBLE: | 491 case base::Value::TYPE_DOUBLE: |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
743 | 718 |
744 if (*additional_properties_schema) { | 719 if (*additional_properties_schema) { |
745 std::string additional_properties_type(schema::kAny); | 720 std::string additional_properties_type(schema::kAny); |
746 CHECK((*additional_properties_schema)->GetString( | 721 CHECK((*additional_properties_schema)->GetString( |
747 schema::kType, &additional_properties_type)); | 722 schema::kType, &additional_properties_type)); |
748 return additional_properties_type == schema::kAny; | 723 return additional_properties_type == schema::kAny; |
749 } else { | 724 } else { |
750 return default_allow_additional_properties_; | 725 return default_allow_additional_properties_; |
751 } | 726 } |
752 } | 727 } |
OLD | NEW |