| 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 |
| 56 bool IsValidSchema(const base::DictionaryValue* dict, std::string* error) { | 68 bool IsValidSchema(const base::DictionaryValue* dict, std::string* error) { |
| 57 // This array must be sorted, so that std::lower_bound can perform a | 69 // This array must be sorted, so that std::lower_bound can perform a |
| 58 // binary search. | 70 // binary search. |
| 59 static const ExpectedType kExpectedTypes[] = { | 71 static const ExpectedType kExpectedTypes[] = { |
| 60 // Note: kRef == "$ref", kSchema == "$schema" | 72 // Note: kRef == "$ref", kSchema == "$schema" |
| 61 { schema::kRef, base::Value::TYPE_STRING }, | 73 { schema::kRef, base::Value::TYPE_STRING }, |
| 62 { schema::kSchema, base::Value::TYPE_STRING }, | 74 { schema::kSchema, base::Value::TYPE_STRING }, |
| 63 | 75 |
| 64 { schema::kAdditionalProperties, base::Value::TYPE_DICTIONARY }, | 76 { schema::kAdditionalProperties, base::Value::TYPE_DICTIONARY }, |
| 65 { schema::kChoices, base::Value::TYPE_LIST }, | 77 { schema::kChoices, base::Value::TYPE_LIST }, |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 return false; | 200 return false; |
| 189 } | 201 } |
| 190 } | 202 } |
| 191 | 203 |
| 192 // Validate the values contained in an "enum" attribute. | 204 // Validate the values contained in an "enum" attribute. |
| 193 if (it.key() == schema::kEnum) { | 205 if (it.key() == schema::kEnum) { |
| 194 it.value().GetAsList(&list_value); | 206 it.value().GetAsList(&list_value); |
| 195 for (size_t i = 0; i < list_value->GetSize(); ++i) { | 207 for (size_t i = 0; i < list_value->GetSize(); ++i) { |
| 196 const base::Value* value = NULL; | 208 const base::Value* value = NULL; |
| 197 list_value->Get(i, &value); | 209 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 } |
| 198 switch (value->GetType()) { | 217 switch (value->GetType()) { |
| 199 case base::Value::TYPE_NULL: | 218 case base::Value::TYPE_NULL: |
| 200 case base::Value::TYPE_BOOLEAN: | 219 case base::Value::TYPE_BOOLEAN: |
| 201 case base::Value::TYPE_INTEGER: | 220 case base::Value::TYPE_INTEGER: |
| 202 case base::Value::TYPE_DOUBLE: | 221 case base::Value::TYPE_DOUBLE: |
| 203 case base::Value::TYPE_STRING: | 222 case base::Value::TYPE_STRING: |
| 204 break; | 223 break; |
| 205 default: | 224 default: |
| 206 *error = "Invalid value in enum attribute"; | 225 *error = "Invalid value in enum attribute"; |
| 207 return false; | 226 return false; |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 errors_.push_back(Error(path, kInvalidChoice)); | 491 errors_.push_back(Error(path, kInvalidChoice)); |
| 473 return; | 492 return; |
| 474 } | 493 } |
| 475 | 494 |
| 476 void JSONSchemaValidator::ValidateEnum(const base::Value* instance, | 495 void JSONSchemaValidator::ValidateEnum(const base::Value* instance, |
| 477 const base::ListValue* choices, | 496 const base::ListValue* choices, |
| 478 const std::string& path) { | 497 const std::string& path) { |
| 479 for (size_t i = 0; i < choices->GetSize(); ++i) { | 498 for (size_t i = 0; i < choices->GetSize(); ++i) { |
| 480 const base::Value* choice = NULL; | 499 const base::Value* choice = NULL; |
| 481 CHECK(choices->Get(i, &choice)); | 500 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 } |
| 482 switch (choice->GetType()) { | 507 switch (choice->GetType()) { |
| 483 case base::Value::TYPE_NULL: | 508 case base::Value::TYPE_NULL: |
| 484 case base::Value::TYPE_BOOLEAN: | 509 case base::Value::TYPE_BOOLEAN: |
| 485 case base::Value::TYPE_STRING: | 510 case base::Value::TYPE_STRING: |
| 486 if (instance->Equals(choice)) | 511 if (instance->Equals(choice)) |
| 487 return; | 512 return; |
| 488 break; | 513 break; |
| 489 | 514 |
| 490 case base::Value::TYPE_INTEGER: | 515 case base::Value::TYPE_INTEGER: |
| 491 case base::Value::TYPE_DOUBLE: | 516 case base::Value::TYPE_DOUBLE: |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 | 743 |
| 719 if (*additional_properties_schema) { | 744 if (*additional_properties_schema) { |
| 720 std::string additional_properties_type(schema::kAny); | 745 std::string additional_properties_type(schema::kAny); |
| 721 CHECK((*additional_properties_schema)->GetString( | 746 CHECK((*additional_properties_schema)->GetString( |
| 722 schema::kType, &additional_properties_type)); | 747 schema::kType, &additional_properties_type)); |
| 723 return additional_properties_type == schema::kAny; | 748 return additional_properties_type == schema::kAny; |
| 724 } else { | 749 } else { |
| 725 return default_allow_additional_properties_; | 750 return default_allow_additional_properties_; |
| 726 } | 751 } |
| 727 } | 752 } |
| OLD | NEW |