| 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/policy/core/common/schema.h" | 5 #include "components/policy/core/common/schema.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <climits> |
| 8 #include <map> | 9 #include <map> |
| 9 #include <utility> | 10 #include <utility> |
| 10 #include <vector> | 11 #include <vector> |
| 11 | 12 |
| 12 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 14 #include "base/memory/scoped_vector.h" | 15 #include "base/memory/scoped_vector.h" |
| 15 #include "components/json_schema/json_schema_constants.h" | 16 #include "components/json_schema/json_schema_constants.h" |
| 16 #include "components/json_schema/json_schema_validator.h" | 17 #include "components/json_schema/json_schema_validator.h" |
| 17 #include "components/policy/core/common/schema_internal.h" | 18 #include "components/policy/core/common/schema_internal.h" |
| 18 | 19 |
| 19 namespace schema = json_schema_constants; | 20 namespace schema = json_schema_constants; |
| 20 | 21 |
| 21 namespace policy { | 22 namespace policy { |
| 22 | 23 |
| 23 using internal::PropertiesNode; | 24 using internal::PropertiesNode; |
| 24 using internal::PropertyNode; | 25 using internal::PropertyNode; |
| 26 using internal::RestrictionNode; |
| 25 using internal::SchemaData; | 27 using internal::SchemaData; |
| 26 using internal::SchemaNode; | 28 using internal::SchemaNode; |
| 27 | 29 |
| 28 namespace { | 30 namespace { |
| 29 | 31 |
| 30 // Maps schema "id" attributes to the corresponding SchemaNode index. | 32 // Maps schema "id" attributes to the corresponding SchemaNode index. |
| 31 typedef std::map<std::string, int> IdMap; | 33 typedef std::map<std::string, int> IdMap; |
| 32 | 34 |
| 33 // List of pairs of references to be assigned later. The string is the "id" | 35 // List of pairs of references to be assigned later. The string is the "id" |
| 34 // whose corresponding index should be stored in the pointer, once all the IDs | 36 // whose corresponding index should be stored in the pointer, once all the IDs |
| 35 // are available. | 37 // are available. |
| 36 typedef std::vector<std::pair<std::string, int*> > ReferenceList; | 38 typedef std::vector<std::pair<std::string, int*> > ReferenceList; |
| 37 | 39 |
| 38 // Sizes for the storage arrays. These are calculated in advance so that the | 40 // Sizes for the storage arrays. These are calculated in advance so that the |
| 39 // arrays don't have to be resized during parsing, which would invalidate | 41 // arrays don't have to be resized during parsing, which would invalidate |
| 40 // pointers into their contents (i.e. string's c_str() and address of indices | 42 // pointers into their contents (i.e. string's c_str() and address of indices |
| 41 // for "$ref" attributes). | 43 // for "$ref" attributes). |
| 42 struct StorageSizes { | 44 struct StorageSizes { |
| 43 StorageSizes() | 45 StorageSizes() |
| 44 : strings(0), schema_nodes(0), property_nodes(0), properties_nodes(0) {} | 46 : strings(0), schema_nodes(0), property_nodes(0), properties_nodes(0), |
| 47 restriction_nodes(0), int_enums(0), string_enums(0) { } |
| 45 size_t strings; | 48 size_t strings; |
| 46 size_t schema_nodes; | 49 size_t schema_nodes; |
| 47 size_t property_nodes; | 50 size_t property_nodes; |
| 48 size_t properties_nodes; | 51 size_t properties_nodes; |
| 52 size_t restriction_nodes; |
| 53 size_t int_enums; |
| 54 size_t string_enums; |
| 49 }; | 55 }; |
| 50 | 56 |
| 51 // An invalid index, indicating that a node is not present; similar to a NULL | 57 // An invalid index, indicating that a node is not present; similar to a NULL |
| 52 // pointer. | 58 // pointer. |
| 53 const int kInvalid = -1; | 59 const int kInvalid = -1; |
| 54 | 60 |
| 55 bool SchemaTypeToValueType(const std::string& type_string, | 61 bool SchemaTypeToValueType(const std::string& type_string, |
| 56 base::Value::Type* type) { | 62 base::Value::Type* type) { |
| 57 // Note: "any" is not an accepted type. | 63 // Note: "any" is not an accepted type. |
| 58 static const struct { | 64 static const struct { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 } | 107 } |
| 102 | 108 |
| 103 const PropertiesNode* properties(int index) const { | 109 const PropertiesNode* properties(int index) const { |
| 104 return schema_data_.properties_nodes + index; | 110 return schema_data_.properties_nodes + index; |
| 105 } | 111 } |
| 106 | 112 |
| 107 const PropertyNode* property(int index) const { | 113 const PropertyNode* property(int index) const { |
| 108 return schema_data_.property_nodes + index; | 114 return schema_data_.property_nodes + index; |
| 109 } | 115 } |
| 110 | 116 |
| 117 const RestrictionNode* restriction(int index) const { |
| 118 return schema_data_.restriction_nodes + index; |
| 119 } |
| 120 |
| 121 const int* int_enums(int index) const { |
| 122 return schema_data_.int_enums + index; |
| 123 } |
| 124 |
| 125 const char** string_enums(int index) const { |
| 126 return schema_data_.string_enums + index; |
| 127 } |
| 128 |
| 111 private: | 129 private: |
| 112 friend class base::RefCountedThreadSafe<InternalStorage>; | 130 friend class base::RefCountedThreadSafe<InternalStorage>; |
| 113 | 131 |
| 114 InternalStorage(); | 132 InternalStorage(); |
| 115 ~InternalStorage(); | 133 ~InternalStorage(); |
| 116 | 134 |
| 117 // Determines the expected |sizes| of the storage for the representation | 135 // Determines the expected |sizes| of the storage for the representation |
| 118 // of |schema|. | 136 // of |schema|. |
| 119 static void DetermineStorageSizes(const base::DictionaryValue& schema, | 137 static void DetermineStorageSizes(const base::DictionaryValue& schema, |
| 120 StorageSizes* sizes); | 138 StorageSizes* sizes); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 145 std::string* error); | 163 std::string* error); |
| 146 | 164 |
| 147 // Helper for Parse() that gets an already assigned |schema_node| instead of | 165 // Helper for Parse() that gets an already assigned |schema_node| instead of |
| 148 // an |index| pointer. | 166 // an |index| pointer. |
| 149 bool ParseList(const base::DictionaryValue& schema, | 167 bool ParseList(const base::DictionaryValue& schema, |
| 150 SchemaNode* schema_node, | 168 SchemaNode* schema_node, |
| 151 IdMap* id_map, | 169 IdMap* id_map, |
| 152 ReferenceList* reference_list, | 170 ReferenceList* reference_list, |
| 153 std::string* error); | 171 std::string* error); |
| 154 | 172 |
| 173 bool ParseEnum(const base::DictionaryValue& schema, |
| 174 base::Value::Type type, |
| 175 SchemaNode* schema_node, |
| 176 std::string* error); |
| 177 |
| 178 bool ParseRangedInt(const base::DictionaryValue& schema, |
| 179 SchemaNode* schema_node, |
| 180 std::string* error); |
| 181 |
| 155 // Assigns the IDs in |id_map| to the pending references in the | 182 // Assigns the IDs in |id_map| to the pending references in the |
| 156 // |reference_list|. If an ID is missing then |error| is set and false is | 183 // |reference_list|. If an ID is missing then |error| is set and false is |
| 157 // returned; otherwise returns true. | 184 // returned; otherwise returns true. |
| 158 static bool ResolveReferences(const IdMap& id_map, | 185 static bool ResolveReferences(const IdMap& id_map, |
| 159 const ReferenceList& reference_list, | 186 const ReferenceList& reference_list, |
| 160 std::string* error); | 187 std::string* error); |
| 161 | 188 |
| 162 SchemaData schema_data_; | 189 SchemaData schema_data_; |
| 163 std::vector<std::string> strings_; | 190 std::vector<std::string> strings_; |
| 164 std::vector<SchemaNode> schema_nodes_; | 191 std::vector<SchemaNode> schema_nodes_; |
| 165 std::vector<PropertyNode> property_nodes_; | 192 std::vector<PropertyNode> property_nodes_; |
| 166 std::vector<PropertiesNode> properties_nodes_; | 193 std::vector<PropertiesNode> properties_nodes_; |
| 194 std::vector<RestrictionNode> restriction_nodes_; |
| 195 std::vector<int> int_enums_; |
| 196 std::vector<const char*> string_enums_; |
| 167 | 197 |
| 168 DISALLOW_COPY_AND_ASSIGN(InternalStorage); | 198 DISALLOW_COPY_AND_ASSIGN(InternalStorage); |
| 169 }; | 199 }; |
| 170 | 200 |
| 171 Schema::InternalStorage::InternalStorage() {} | 201 Schema::InternalStorage::InternalStorage() {} |
| 172 | 202 |
| 173 Schema::InternalStorage::~InternalStorage() {} | 203 Schema::InternalStorage::~InternalStorage() {} |
| 174 | 204 |
| 175 // static | 205 // static |
| 176 scoped_refptr<const Schema::InternalStorage> Schema::InternalStorage::Wrap( | 206 scoped_refptr<const Schema::InternalStorage> Schema::InternalStorage::Wrap( |
| 177 const SchemaData* data) { | 207 const SchemaData* data) { |
| 178 InternalStorage* storage = new InternalStorage(); | 208 InternalStorage* storage = new InternalStorage(); |
| 179 storage->schema_data_.schema_nodes = data->schema_nodes; | 209 storage->schema_data_.schema_nodes = data->schema_nodes; |
| 180 storage->schema_data_.property_nodes = data->property_nodes; | 210 storage->schema_data_.property_nodes = data->property_nodes; |
| 181 storage->schema_data_.properties_nodes = data->properties_nodes; | 211 storage->schema_data_.properties_nodes = data->properties_nodes; |
| 212 storage->schema_data_.restriction_nodes = data->restriction_nodes; |
| 213 storage->schema_data_.int_enums = data->int_enums; |
| 214 storage->schema_data_.string_enums = data->string_enums; |
| 182 return storage; | 215 return storage; |
| 183 } | 216 } |
| 184 | 217 |
| 185 // static | 218 // static |
| 186 scoped_refptr<const Schema::InternalStorage> | 219 scoped_refptr<const Schema::InternalStorage> |
| 187 Schema::InternalStorage::ParseSchema(const base::DictionaryValue& schema, | 220 Schema::InternalStorage::ParseSchema(const base::DictionaryValue& schema, |
| 188 std::string* error) { | 221 std::string* error) { |
| 189 // Determine the sizes of the storage arrays and reserve the capacity before | 222 // Determine the sizes of the storage arrays and reserve the capacity before |
| 190 // starting to append nodes and strings. This is important to prevent the | 223 // starting to append nodes and strings. This is important to prevent the |
| 191 // arrays from being reallocated, which would invalidate the c_str() pointers | 224 // arrays from being reallocated, which would invalidate the c_str() pointers |
| 192 // and the addresses of indices to fix. | 225 // and the addresses of indices to fix. |
| 193 StorageSizes sizes; | 226 StorageSizes sizes; |
| 194 DetermineStorageSizes(schema, &sizes); | 227 DetermineStorageSizes(schema, &sizes); |
| 195 | 228 |
| 196 scoped_refptr<InternalStorage> storage = new InternalStorage(); | 229 scoped_refptr<InternalStorage> storage = new InternalStorage(); |
| 197 storage->strings_.reserve(sizes.strings); | 230 storage->strings_.reserve(sizes.strings); |
| 198 storage->schema_nodes_.reserve(sizes.schema_nodes); | 231 storage->schema_nodes_.reserve(sizes.schema_nodes); |
| 199 storage->property_nodes_.reserve(sizes.property_nodes); | 232 storage->property_nodes_.reserve(sizes.property_nodes); |
| 200 storage->properties_nodes_.reserve(sizes.properties_nodes); | 233 storage->properties_nodes_.reserve(sizes.properties_nodes); |
| 234 storage->restriction_nodes_.reserve(sizes.restriction_nodes); |
| 235 storage->int_enums_.reserve(sizes.int_enums); |
| 236 storage->string_enums_.reserve(sizes.string_enums); |
| 201 | 237 |
| 202 int root_index = kInvalid; | 238 int root_index = kInvalid; |
| 203 IdMap id_map; | 239 IdMap id_map; |
| 204 ReferenceList reference_list; | 240 ReferenceList reference_list; |
| 205 if (!storage->Parse(schema, &root_index, &id_map, &reference_list, error)) | 241 if (!storage->Parse(schema, &root_index, &id_map, &reference_list, error)) |
| 206 return NULL; | 242 return NULL; |
| 207 | 243 |
| 208 if (root_index == kInvalid) { | 244 if (root_index == kInvalid) { |
| 209 *error = "The main schema can't have a $ref"; | 245 *error = "The main schema can't have a $ref"; |
| 210 return NULL; | 246 return NULL; |
| 211 } | 247 } |
| 212 | 248 |
| 213 // None of this should ever happen without having been already detected. | 249 // None of this should ever happen without having been already detected. |
| 214 // But, if it does happen, then it will lead to corrupted memory; drop | 250 // But, if it does happen, then it will lead to corrupted memory; drop |
| 215 // everything in that case. | 251 // everything in that case. |
| 216 if (root_index != 0 || | 252 if (root_index != 0 || |
| 217 sizes.strings != storage->strings_.size() || | 253 sizes.strings != storage->strings_.size() || |
| 218 sizes.schema_nodes != storage->schema_nodes_.size() || | 254 sizes.schema_nodes != storage->schema_nodes_.size() || |
| 219 sizes.property_nodes != storage->property_nodes_.size() || | 255 sizes.property_nodes != storage->property_nodes_.size() || |
| 220 sizes.properties_nodes != storage->properties_nodes_.size()) { | 256 sizes.properties_nodes != storage->properties_nodes_.size() || |
| 257 sizes.restriction_nodes != storage->restriction_nodes_.size() || |
| 258 sizes.int_enums != storage->int_enums_.size() || |
| 259 sizes.string_enums != storage->string_enums_.size()) { |
| 221 *error = "Failed to parse the schema due to a Chrome bug. Please file a " | 260 *error = "Failed to parse the schema due to a Chrome bug. Please file a " |
| 222 "new issue at http://crbug.com"; | 261 "new issue at http://crbug.com"; |
| 223 return NULL; | 262 return NULL; |
| 224 } | 263 } |
| 225 | 264 |
| 226 if (!ResolveReferences(id_map, reference_list, error)) | 265 if (!ResolveReferences(id_map, reference_list, error)) |
| 227 return NULL; | 266 return NULL; |
| 228 | 267 |
| 229 SchemaData* data = &storage->schema_data_; | 268 SchemaData* data = &storage->schema_data_; |
| 230 data->schema_nodes = vector_as_array(&storage->schema_nodes_); | 269 data->schema_nodes = vector_as_array(&storage->schema_nodes_); |
| 231 data->property_nodes = vector_as_array(&storage->property_nodes_); | 270 data->property_nodes = vector_as_array(&storage->property_nodes_); |
| 232 data->properties_nodes = vector_as_array(&storage->properties_nodes_); | 271 data->properties_nodes = vector_as_array(&storage->properties_nodes_); |
| 272 data->restriction_nodes = vector_as_array(&storage->restriction_nodes_); |
| 273 data->int_enums = vector_as_array(&storage->int_enums_); |
| 274 data->string_enums = vector_as_array(&storage->string_enums_); |
| 233 return storage; | 275 return storage; |
| 234 } | 276 } |
| 235 | 277 |
| 236 // static | 278 // static |
| 237 void Schema::InternalStorage::DetermineStorageSizes( | 279 void Schema::InternalStorage::DetermineStorageSizes( |
| 238 const base::DictionaryValue& schema, | 280 const base::DictionaryValue& schema, |
| 239 StorageSizes* sizes) { | 281 StorageSizes* sizes) { |
| 240 std::string ref_string; | 282 std::string ref_string; |
| 241 if (schema.GetString(schema::kRef, &ref_string)) { | 283 if (schema.GetString(schema::kRef, &ref_string)) { |
| 242 // Schemas with a "$ref" attribute don't take additional storage. | 284 // Schemas with a "$ref" attribute don't take additional storage. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 268 if (schema.GetDictionary(schema::kProperties, &properties)) { | 310 if (schema.GetDictionary(schema::kProperties, &properties)) { |
| 269 for (base::DictionaryValue::Iterator it(*properties); | 311 for (base::DictionaryValue::Iterator it(*properties); |
| 270 !it.IsAtEnd(); it.Advance()) { | 312 !it.IsAtEnd(); it.Advance()) { |
| 271 // This should have been verified by the JSONSchemaValidator. | 313 // This should have been verified by the JSONSchemaValidator. |
| 272 CHECK(it.value().GetAsDictionary(&dict)); | 314 CHECK(it.value().GetAsDictionary(&dict)); |
| 273 DetermineStorageSizes(*dict, sizes); | 315 DetermineStorageSizes(*dict, sizes); |
| 274 sizes->strings++; | 316 sizes->strings++; |
| 275 sizes->property_nodes++; | 317 sizes->property_nodes++; |
| 276 } | 318 } |
| 277 } | 319 } |
| 320 } else if (schema.HasKey(schema::kEnum)) { |
| 321 const base::ListValue* possible_values = NULL; |
| 322 if (schema.GetList(schema::kEnum, &possible_values)) { |
| 323 if (type == base::Value::TYPE_INTEGER) { |
| 324 sizes->int_enums += possible_values->GetSize(); |
| 325 } else if (type == base::Value::TYPE_STRING) { |
| 326 sizes->string_enums += possible_values->GetSize(); |
| 327 sizes->strings += possible_values->GetSize(); |
| 328 } |
| 329 sizes->restriction_nodes++; |
| 330 } |
| 331 } else if (type == base::Value::TYPE_INTEGER) { |
| 332 if (schema.HasKey(schema::kMinimum) || schema.HasKey(schema::kMaximum)) |
| 333 sizes->restriction_nodes++; |
| 278 } | 334 } |
| 279 } | 335 } |
| 280 | 336 |
| 281 bool Schema::InternalStorage::Parse(const base::DictionaryValue& schema, | 337 bool Schema::InternalStorage::Parse(const base::DictionaryValue& schema, |
| 282 int* index, | 338 int* index, |
| 283 IdMap* id_map, | 339 IdMap* id_map, |
| 284 ReferenceList* reference_list, | 340 ReferenceList* reference_list, |
| 285 std::string* error) { | 341 std::string* error) { |
| 286 std::string ref_string; | 342 std::string ref_string; |
| 287 if (schema.GetString(schema::kRef, &ref_string)) { | 343 if (schema.GetString(schema::kRef, &ref_string)) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 311 SchemaNode* schema_node = &schema_nodes_.back(); | 367 SchemaNode* schema_node = &schema_nodes_.back(); |
| 312 schema_node->type = type; | 368 schema_node->type = type; |
| 313 schema_node->extra = kInvalid; | 369 schema_node->extra = kInvalid; |
| 314 | 370 |
| 315 if (type == base::Value::TYPE_DICTIONARY) { | 371 if (type == base::Value::TYPE_DICTIONARY) { |
| 316 if (!ParseDictionary(schema, schema_node, id_map, reference_list, error)) | 372 if (!ParseDictionary(schema, schema_node, id_map, reference_list, error)) |
| 317 return false; | 373 return false; |
| 318 } else if (type == base::Value::TYPE_LIST) { | 374 } else if (type == base::Value::TYPE_LIST) { |
| 319 if (!ParseList(schema, schema_node, id_map, reference_list, error)) | 375 if (!ParseList(schema, schema_node, id_map, reference_list, error)) |
| 320 return false; | 376 return false; |
| 377 } else if (schema.HasKey(schema::kEnum)) { |
| 378 if (!ParseEnum(schema, type, schema_node, error)) |
| 379 return false; |
| 380 } else if (schema.HasKey(schema::kMinimum) || |
| 381 schema.HasKey(schema::kMaximum)) { |
| 382 if (type != base::Value::TYPE_INTEGER) { |
| 383 *error = "Only integers can have minimum and maximum"; |
| 384 return false; |
| 385 } |
| 386 if (!ParseRangedInt(schema, schema_node, error)) |
| 387 return false; |
| 321 } | 388 } |
| 322 | |
| 323 std::string id_string; | 389 std::string id_string; |
| 324 if (schema.GetString(schema::kId, &id_string)) { | 390 if (schema.GetString(schema::kId, &id_string)) { |
| 325 if (ContainsKey(*id_map, id_string)) { | 391 if (ContainsKey(*id_map, id_string)) { |
| 326 *error = "Duplicated id: " + id_string; | 392 *error = "Duplicated id: " + id_string; |
| 327 return false; | 393 return false; |
| 328 } | 394 } |
| 329 (*id_map)[id_string] = *index; | 395 (*id_map)[id_string] = *index; |
| 330 } | 396 } |
| 331 | 397 |
| 332 return true; | 398 return true; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 ReferenceList* reference_list, | 453 ReferenceList* reference_list, |
| 388 std::string* error) { | 454 std::string* error) { |
| 389 const base::DictionaryValue* dict = NULL; | 455 const base::DictionaryValue* dict = NULL; |
| 390 if (!schema.GetDictionary(schema::kItems, &dict)) { | 456 if (!schema.GetDictionary(schema::kItems, &dict)) { |
| 391 *error = "Arrays must declare a single schema for their items."; | 457 *error = "Arrays must declare a single schema for their items."; |
| 392 return false; | 458 return false; |
| 393 } | 459 } |
| 394 return Parse(*dict, &schema_node->extra, id_map, reference_list, error); | 460 return Parse(*dict, &schema_node->extra, id_map, reference_list, error); |
| 395 } | 461 } |
| 396 | 462 |
| 463 bool Schema::InternalStorage::ParseEnum(const base::DictionaryValue& schema, |
| 464 base::Value::Type type, |
| 465 SchemaNode* schema_node, |
| 466 std::string* error) { |
| 467 const base::ListValue *possible_values = NULL; |
| 468 if (!schema.GetList(schema::kEnum, &possible_values)) { |
| 469 *error = "Enum attribute must be a list value"; |
| 470 return false; |
| 471 } |
| 472 if (possible_values->empty()) { |
| 473 *error = "Enum attribute must be non-empty"; |
| 474 return false; |
| 475 } |
| 476 int offset_begin; |
| 477 int offset_end; |
| 478 if (type == base::Value::TYPE_INTEGER) { |
| 479 offset_begin = static_cast<int>(int_enums_.size()); |
| 480 int value; |
| 481 for (base::ListValue::const_iterator it = possible_values->begin(); |
| 482 it != possible_values->end(); ++it) { |
| 483 if (!(*it)->GetAsInteger(&value)) { |
| 484 *error = "Invalid enumeration member type"; |
| 485 return false; |
| 486 } |
| 487 int_enums_.push_back(value); |
| 488 } |
| 489 offset_end = static_cast<int>(int_enums_.size()); |
| 490 } else if (type == base::Value::TYPE_STRING) { |
| 491 offset_begin = static_cast<int>(string_enums_.size()); |
| 492 std::string value; |
| 493 for (base::ListValue::const_iterator it = possible_values->begin(); |
| 494 it != possible_values->end(); ++it) { |
| 495 if (!(*it)->GetAsString(&value)) { |
| 496 *error = "Invalid enumeration member type"; |
| 497 return false; |
| 498 } |
| 499 strings_.push_back(value); |
| 500 string_enums_.push_back(strings_.back().c_str()); |
| 501 } |
| 502 offset_end = static_cast<int>(string_enums_.size()); |
| 503 } else { |
| 504 *error = "Enumeration is only supported for integer and string."; |
| 505 return false; |
| 506 } |
| 507 schema_node->extra = static_cast<int>(restriction_nodes_.size()); |
| 508 restriction_nodes_.push_back(RestrictionNode()); |
| 509 restriction_nodes_.back().enumeration_restriction.offset_begin = offset_begin; |
| 510 restriction_nodes_.back().enumeration_restriction.offset_end = offset_end; |
| 511 return true; |
| 512 } |
| 513 |
| 514 bool Schema::InternalStorage::ParseRangedInt( |
| 515 const base::DictionaryValue& schema, |
| 516 SchemaNode* schema_node, |
| 517 std::string* error) { |
| 518 int min_value = INT_MIN; |
| 519 int max_value = INT_MAX; |
| 520 int value; |
| 521 if (schema.GetInteger(schema::kMinimum, &value)) |
| 522 min_value = value; |
| 523 if (schema.GetInteger(schema::kMaximum, &value)) |
| 524 max_value = value; |
| 525 if (min_value > max_value) { |
| 526 *error = "Invalid range restriction for int type."; |
| 527 return false; |
| 528 } |
| 529 schema_node->extra = static_cast<int>(restriction_nodes_.size()); |
| 530 restriction_nodes_.push_back(RestrictionNode()); |
| 531 restriction_nodes_.back().ranged_restriction.max_value = max_value; |
| 532 restriction_nodes_.back().ranged_restriction.min_value = min_value; |
| 533 return true; |
| 534 } |
| 535 |
| 397 // static | 536 // static |
| 398 bool Schema::InternalStorage::ResolveReferences( | 537 bool Schema::InternalStorage::ResolveReferences( |
| 399 const IdMap& id_map, | 538 const IdMap& id_map, |
| 400 const ReferenceList& reference_list, | 539 const ReferenceList& reference_list, |
| 401 std::string* error) { | 540 std::string* error) { |
| 402 for (ReferenceList::const_iterator ref = reference_list.begin(); | 541 for (ReferenceList::const_iterator ref = reference_list.begin(); |
| 403 ref != reference_list.end(); ++ref) { | 542 ref != reference_list.end(); ++ref) { |
| 404 IdMap::const_iterator id = id_map.find(ref->first); | 543 IdMap::const_iterator id = id_map.find(ref->first); |
| 405 if (id == id_map.end()) { | 544 if (id == id_map.end()) { |
| 406 *error = "Invalid $ref: " + ref->first; | 545 *error = "Invalid $ref: " + ref->first; |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 | 717 |
| 579 Schema Schema::GetItems() const { | 718 Schema Schema::GetItems() const { |
| 580 CHECK(valid()); | 719 CHECK(valid()); |
| 581 CHECK_EQ(base::Value::TYPE_LIST, type()); | 720 CHECK_EQ(base::Value::TYPE_LIST, type()); |
| 582 if (node_->extra == kInvalid) | 721 if (node_->extra == kInvalid) |
| 583 return Schema(); | 722 return Schema(); |
| 584 return Schema(storage_, storage_->schema(node_->extra)); | 723 return Schema(storage_, storage_->schema(node_->extra)); |
| 585 } | 724 } |
| 586 | 725 |
| 587 } // namespace policy | 726 } // namespace policy |
| OLD | NEW |