| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // ----------------------------------------------------------------------------- | 5 // ----------------------------------------------------------------------------- |
| 6 // NOTE: If you change this file you need to touch renderer_resources.grd to | 6 // NOTE: If you change this file you need to touch renderer_resources.grd to |
| 7 // have your change take effect. | 7 // have your change take effect. |
| 8 // ----------------------------------------------------------------------------- | 8 // ----------------------------------------------------------------------------- |
| 9 | 9 |
| 10 //============================================================================== | 10 //============================================================================== |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 if (typeOrTypeList instanceof Array) { | 137 if (typeOrTypeList instanceof Array) { |
| 138 for (var i = 0; i < typeOrTypeList.length; i++) { | 138 for (var i = 0; i < typeOrTypeList.length; i++) { |
| 139 addType(this, typeOrTypeList[i]); | 139 addType(this, typeOrTypeList[i]); |
| 140 } | 140 } |
| 141 } else { | 141 } else { |
| 142 addType(this, typeOrTypeList); | 142 addType(this, typeOrTypeList); |
| 143 } | 143 } |
| 144 } | 144 } |
| 145 | 145 |
| 146 /** | 146 /** |
| 147 * Returns a list of strings of the types that this schema accepts. |
| 148 */ |
| 149 chromeHidden.JSONSchemaValidator.prototype.getAllTypesForSchema = |
| 150 function(schema) { |
| 151 var schemaTypes = []; |
| 152 if (schema.type) |
| 153 schemaTypes.push(schema.type); |
| 154 if (schema.choices) { |
| 155 for (var i = 0; i < schema.choices.length; i++) { |
| 156 var choiceTypes = this.getAllTypesForSchema(schema.choices[i]); |
| 157 schemaTypes = schemaTypes.concat(choiceTypes); |
| 158 } |
| 159 } |
| 160 if (schema['$ref']) { |
| 161 var refTypes = this.getAllTypesForSchema(this.types[schema['$ref']]); |
| 162 schemaTypes = schemaTypes.concat(refTypes); |
| 163 } |
| 164 return schemaTypes; |
| 165 }; |
| 166 |
| 167 /** |
| 168 * Returns true if |schema| would accept an argument of type |type|. |
| 169 */ |
| 170 chromeHidden.JSONSchemaValidator.prototype.isValidSchemaType = |
| 171 function(type, schema) { |
| 172 if (schema.optional && (type == "null" || type == "undefined")) |
| 173 return true; |
| 174 |
| 175 schemaTypes = this.getAllTypesForSchema(schema); |
| 176 for (var i = 0; i < schemaTypes.length; i++) { |
| 177 if (schemaTypes[i] == "any" || type == schemaTypes[i]) |
| 178 return true; |
| 179 } |
| 180 return type == "any"; |
| 181 }; |
| 182 |
| 183 /** |
| 184 * Returns true if there is a non-null argument that both |schema1| and |
| 185 * |schema2| would accept. |
| 186 */ |
| 187 chromeHidden.JSONSchemaValidator.prototype.checkSchemaOverlap = |
| 188 function(schema1, schema2) { |
| 189 var schema1Types = this.getAllTypesForSchema(schema1); |
| 190 for (var i = 0; i < schema1Types.length; i++) { |
| 191 if (this.isValidSchemaType(schema1Types[i], schema2)) |
| 192 return true; |
| 193 } |
| 194 return false; |
| 195 }; |
| 196 |
| 197 /** |
| 147 * Validates an instance against a schema. The instance can be any JavaScript | 198 * Validates an instance against a schema. The instance can be any JavaScript |
| 148 * value and will be validated recursively. When this method returns, the | 199 * value and will be validated recursively. When this method returns, the |
| 149 * |errors| property will contain a list of errors, if any. | 200 * |errors| property will contain a list of errors, if any. |
| 150 */ | 201 */ |
| 151 chromeHidden.JSONSchemaValidator.prototype.validate = function( | 202 chromeHidden.JSONSchemaValidator.prototype.validate = |
| 152 instance, schema, opt_path) { | 203 function(instance, schema, opt_path) { |
| 153 var path = opt_path || ""; | 204 var path = opt_path || ""; |
| 154 | 205 |
| 155 if (!schema) { | 206 if (!schema) { |
| 156 this.addError(path, "schemaRequired"); | 207 this.addError(path, "schemaRequired"); |
| 157 return; | 208 return; |
| 158 } | 209 } |
| 159 | 210 |
| 160 // If this schema defines itself as reference type, save it in this.types. | 211 // If this schema defines itself as reference type, save it in this.types. |
| 161 if (schema.id) | 212 if (schema.id) |
| 162 this.types[schema.id] = schema; | 213 this.types[schema.id] = schema; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 this.validateNumber(instance, schema, path); | 260 this.validateNumber(instance, schema, path); |
| 210 break; | 261 break; |
| 211 } | 262 } |
| 212 } | 263 } |
| 213 }; | 264 }; |
| 214 | 265 |
| 215 /** | 266 /** |
| 216 * Validates an instance against a choices schema. The instance must match at | 267 * Validates an instance against a choices schema. The instance must match at |
| 217 * least one of the provided choices. | 268 * least one of the provided choices. |
| 218 */ | 269 */ |
| 219 chromeHidden.JSONSchemaValidator.prototype.validateChoices = function( | 270 chromeHidden.JSONSchemaValidator.prototype.validateChoices = |
| 220 instance, schema, path) { | 271 function(instance, schema, path) { |
| 221 var originalErrors = this.errors; | 272 var originalErrors = this.errors; |
| 222 | 273 |
| 223 for (var i = 0; i < schema.choices.length; i++) { | 274 for (var i = 0; i < schema.choices.length; i++) { |
| 224 this.errors = []; | 275 this.errors = []; |
| 225 this.validate(instance, schema.choices[i], path); | 276 this.validate(instance, schema.choices[i], path); |
| 226 if (this.errors.length == 0) { | 277 if (this.errors.length == 0) { |
| 227 this.errors = originalErrors; | 278 this.errors = originalErrors; |
| 228 return; | 279 return; |
| 229 } | 280 } |
| 230 } | 281 } |
| 231 | 282 |
| 232 this.errors = originalErrors; | 283 this.errors = originalErrors; |
| 233 this.addError(path, "invalidChoice"); | 284 this.addError(path, "invalidChoice"); |
| 234 }; | 285 }; |
| 235 | 286 |
| 236 /** | 287 /** |
| 237 * Validates an instance against a schema with an enum type. Populates the | 288 * Validates an instance against a schema with an enum type. Populates the |
| 238 * |errors| property, and returns a boolean indicating whether the instance | 289 * |errors| property, and returns a boolean indicating whether the instance |
| 239 * validates. | 290 * validates. |
| 240 */ | 291 */ |
| 241 chromeHidden.JSONSchemaValidator.prototype.validateEnum = function( | 292 chromeHidden.JSONSchemaValidator.prototype.validateEnum = |
| 242 instance, schema, path) { | 293 function(instance, schema, path) { |
| 243 for (var i = 0; i < schema.enum.length; i++) { | 294 for (var i = 0; i < schema.enum.length; i++) { |
| 244 if (instance === schema.enum[i]) | 295 if (instance === schema.enum[i]) |
| 245 return true; | 296 return true; |
| 246 } | 297 } |
| 247 | 298 |
| 248 this.addError(path, "invalidEnum", [schema.enum.join(", ")]); | 299 this.addError(path, "invalidEnum", [schema.enum.join(", ")]); |
| 249 return false; | 300 return false; |
| 250 }; | 301 }; |
| 251 | 302 |
| 252 /** | 303 /** |
| 253 * Validates an instance against an object schema and populates the errors | 304 * Validates an instance against an object schema and populates the errors |
| 254 * property. | 305 * property. |
| 255 */ | 306 */ |
| 256 chromeHidden.JSONSchemaValidator.prototype.validateObject = function( | 307 chromeHidden.JSONSchemaValidator.prototype.validateObject = |
| 257 instance, schema, path) { | 308 function(instance, schema, path) { |
| 258 if (schema.properties) { | 309 if (schema.properties) { |
| 259 for (var prop in schema.properties) { | 310 for (var prop in schema.properties) { |
| 260 // It is common in JavaScript to add properties to Object.prototype. This | 311 // It is common in JavaScript to add properties to Object.prototype. This |
| 261 // check prevents such additions from being interpreted as required | 312 // check prevents such additions from being interpreted as required |
| 262 // schema properties. | 313 // schema properties. |
| 263 // TODO(aa): If it ever turns out that we actually want this to work, | 314 // TODO(aa): If it ever turns out that we actually want this to work, |
| 264 // there are other checks we could put here, like requiring that schema | 315 // there are other checks we could put here, like requiring that schema |
| 265 // properties be objects that have a 'type' property. | 316 // properties be objects that have a 'type' property. |
| 266 if (!schema.properties.hasOwnProperty(prop)) | 317 if (!schema.properties.hasOwnProperty(prop)) |
| 267 continue; | 318 continue; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 this.validate(instance[prop], schema.additionalProperties, propPath); | 360 this.validate(instance[prop], schema.additionalProperties, propPath); |
| 310 else | 361 else |
| 311 this.addError(propPath, "unexpectedProperty"); | 362 this.addError(propPath, "unexpectedProperty"); |
| 312 } | 363 } |
| 313 }; | 364 }; |
| 314 | 365 |
| 315 /** | 366 /** |
| 316 * Validates an instance against an array schema and populates the errors | 367 * Validates an instance against an array schema and populates the errors |
| 317 * property. | 368 * property. |
| 318 */ | 369 */ |
| 319 chromeHidden.JSONSchemaValidator.prototype.validateArray = function( | 370 chromeHidden.JSONSchemaValidator.prototype.validateArray = |
| 320 instance, schema, path) { | 371 function(instance, schema, path) { |
| 321 var typeOfItems = chromeHidden.JSONSchemaValidator.getType(schema.items); | 372 var typeOfItems = chromeHidden.JSONSchemaValidator.getType(schema.items); |
| 322 | 373 |
| 323 if (typeOfItems == 'object') { | 374 if (typeOfItems == 'object') { |
| 324 if (schema.minItems && instance.length < schema.minItems) { | 375 if (schema.minItems && instance.length < schema.minItems) { |
| 325 this.addError(path, "arrayMinItems", [schema.minItems]); | 376 this.addError(path, "arrayMinItems", [schema.minItems]); |
| 326 } | 377 } |
| 327 | 378 |
| 328 if (typeof schema.maxItems != "undefined" && | 379 if (typeof schema.maxItems != "undefined" && |
| 329 instance.length > schema.maxItems) { | 380 instance.length > schema.maxItems) { |
| 330 this.addError(path, "arrayMaxItems", [schema.maxItems]); | 381 this.addError(path, "arrayMaxItems", [schema.maxItems]); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 356 if (instance.length > schema.items.length) { | 407 if (instance.length > schema.items.length) { |
| 357 this.addError(path, "arrayMaxItems", [schema.items.length]); | 408 this.addError(path, "arrayMaxItems", [schema.items.length]); |
| 358 } | 409 } |
| 359 } | 410 } |
| 360 } | 411 } |
| 361 }; | 412 }; |
| 362 | 413 |
| 363 /** | 414 /** |
| 364 * Validates a string and populates the errors property. | 415 * Validates a string and populates the errors property. |
| 365 */ | 416 */ |
| 366 chromeHidden.JSONSchemaValidator.prototype.validateString = function( | 417 chromeHidden.JSONSchemaValidator.prototype.validateString = |
| 367 instance, schema, path) { | 418 function(instance, schema, path) { |
| 368 if (schema.minLength && instance.length < schema.minLength) | 419 if (schema.minLength && instance.length < schema.minLength) |
| 369 this.addError(path, "stringMinLength", [schema.minLength]); | 420 this.addError(path, "stringMinLength", [schema.minLength]); |
| 370 | 421 |
| 371 if (schema.maxLength && instance.length > schema.maxLength) | 422 if (schema.maxLength && instance.length > schema.maxLength) |
| 372 this.addError(path, "stringMaxLength", [schema.maxLength]); | 423 this.addError(path, "stringMaxLength", [schema.maxLength]); |
| 373 | 424 |
| 374 if (schema.pattern && !schema.pattern.test(instance)) | 425 if (schema.pattern && !schema.pattern.test(instance)) |
| 375 this.addError(path, "stringPattern", [schema.pattern]); | 426 this.addError(path, "stringPattern", [schema.pattern]); |
| 376 }; | 427 }; |
| 377 | 428 |
| 378 /** | 429 /** |
| 379 * Validates a number and populates the errors property. The instance is | 430 * Validates a number and populates the errors property. The instance is |
| 380 * assumed to be a number. | 431 * assumed to be a number. |
| 381 */ | 432 */ |
| 382 chromeHidden.JSONSchemaValidator.prototype.validateNumber = function( | 433 chromeHidden.JSONSchemaValidator.prototype.validateNumber = |
| 383 instance, schema, path) { | 434 function(instance, schema, path) { |
| 384 | 435 |
| 385 // Forbid NaN, +Infinity, and -Infinity. Our APIs don't use them, and | 436 // Forbid NaN, +Infinity, and -Infinity. Our APIs don't use them, and |
| 386 // JSON serialization encodes them as 'null'. Re-evaluate supporting | 437 // JSON serialization encodes them as 'null'. Re-evaluate supporting |
| 387 // them if we add an API that could reasonably take them as a parameter. | 438 // them if we add an API that could reasonably take them as a parameter. |
| 388 if (isNaN(instance) || | 439 if (isNaN(instance) || |
| 389 instance == Number.POSITIVE_INFINITY || | 440 instance == Number.POSITIVE_INFINITY || |
| 390 instance == Number.NEGATIVE_INFINITY ) | 441 instance == Number.NEGATIVE_INFINITY ) |
| 391 this.addError(path, "numberFiniteNotNan", [instance]); | 442 this.addError(path, "numberFiniteNotNan", [instance]); |
| 392 | 443 |
| 393 if (schema.minimum !== undefined && instance < schema.minimum) | 444 if (schema.minimum !== undefined && instance < schema.minimum) |
| 394 this.addError(path, "numberMinValue", [schema.minimum]); | 445 this.addError(path, "numberMinValue", [schema.minimum]); |
| 395 | 446 |
| 396 if (schema.maximum !== undefined && instance > schema.maximum) | 447 if (schema.maximum !== undefined && instance > schema.maximum) |
| 397 this.addError(path, "numberMaxValue", [schema.maximum]); | 448 this.addError(path, "numberMaxValue", [schema.maximum]); |
| 398 | 449 |
| 399 // Check for integer values outside of -2^31..2^31-1. | 450 // Check for integer values outside of -2^31..2^31-1. |
| 400 if (schema.type === "integer" && (instance | 0) !== instance) | 451 if (schema.type === "integer" && (instance | 0) !== instance) |
| 401 this.addError(path, "numberIntValue", []); | 452 this.addError(path, "numberIntValue", []); |
| 402 | 453 |
| 403 if (schema.maxDecimal && instance * Math.pow(10, schema.maxDecimal) % 1) | 454 if (schema.maxDecimal && instance * Math.pow(10, schema.maxDecimal) % 1) |
| 404 this.addError(path, "numberMaxDecimal", [schema.maxDecimal]); | 455 this.addError(path, "numberMaxDecimal", [schema.maxDecimal]); |
| 405 }; | 456 }; |
| 406 | 457 |
| 407 /** | 458 /** |
| 408 * Validates the primitive type of an instance and populates the errors | 459 * Validates the primitive type of an instance and populates the errors |
| 409 * property. Returns true if the instance validates, false otherwise. | 460 * property. Returns true if the instance validates, false otherwise. |
| 410 */ | 461 */ |
| 411 chromeHidden.JSONSchemaValidator.prototype.validateType = function( | 462 chromeHidden.JSONSchemaValidator.prototype.validateType = |
| 412 instance, schema, path) { | 463 function(instance, schema, path) { |
| 413 var actualType = chromeHidden.JSONSchemaValidator.getType(instance); | 464 var actualType = chromeHidden.JSONSchemaValidator.getType(instance); |
| 414 if (schema.type != actualType && !(schema.type == "number" && | 465 if (schema.type != actualType && !(schema.type == "number" && |
| 415 actualType == "integer")) { | 466 actualType == "integer")) { |
| 416 this.addError(path, "invalidType", [schema.type, actualType]); | 467 this.addError(path, "invalidType", [schema.type, actualType]); |
| 417 return false; | 468 return false; |
| 418 } | 469 } |
| 419 | 470 |
| 420 return true; | 471 return true; |
| 421 }; | 472 }; |
| 422 | 473 |
| 423 /** | 474 /** |
| 424 * Adds an error message. |key| is an index into the |messages| object. | 475 * Adds an error message. |key| is an index into the |messages| object. |
| 425 * |replacements| is an array of values to replace '*' characters in the | 476 * |replacements| is an array of values to replace '*' characters in the |
| 426 * message. | 477 * message. |
| 427 */ | 478 */ |
| 428 chromeHidden.JSONSchemaValidator.prototype.addError = function( | 479 chromeHidden.JSONSchemaValidator.prototype.addError = |
| 429 path, key, replacements) { | 480 function(path, key, replacements) { |
| 430 this.errors.push({ | 481 this.errors.push({ |
| 431 path: path, | 482 path: path, |
| 432 message: chromeHidden.JSONSchemaValidator.formatError(key, replacements) | 483 message: chromeHidden.JSONSchemaValidator.formatError(key, replacements) |
| 433 }); | 484 }); |
| 434 }; | 485 }; |
| 435 | 486 |
| 487 /** |
| 488 * Resets errors to an empty list so you can call 'validate' again. |
| 489 */ |
| 490 chromeHidden.JSONSchemaValidator.prototype.resetErrors = function() { |
| 491 this.errors = []; |
| 492 }; |
| 493 |
| 436 })(); | 494 })(); |
| OLD | NEW |