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 |