Chromium Code Reviews| Index: mojo/public/js/bindings/validator.js |
| diff --git a/mojo/public/js/bindings/validator.js b/mojo/public/js/bindings/validator.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..3066e8011633926d9b9c1a91c98bf2b776305547 |
| --- /dev/null |
| +++ b/mojo/public/js/bindings/validator.js |
| @@ -0,0 +1,93 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +define("mojo/public/js/bindings/validator", [ |
| + "mojo/public/js/bindings/codec", |
| + ], function(codec) { |
| + |
| + var ValidationError = { |
| + NONE: 'VALIDATION_ERROR_NONE', |
| + MISALIGNED_OBJECT: 'VALIDATION_ERROR_MISALIGNED_OBJECT', |
| + ILLEGAL_MEMORY_RANGE: 'VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE', |
| + UNEXPECTED_STRUCT_HEADER: 'VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER', |
| + UNEXPECTED_ARRAY_HEADER: 'VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER', |
| + ILLEGAL_HANDLE: 'VALIDATION_ERROR_ILLEGAL_HANDLE', |
| + ILLEGAL_POINTER: 'VALIDATION_ERROR_ILLEGAL_POINTER', |
| + MESSAGE_HEADER_INVALID_FLAG_COMBINATION: |
| + 'VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINATION', |
| + MESSAGE_HEADER_MISSING_REQUEST_ID: |
| + 'VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID' |
| + }; |
| + |
| + function Validator(message, offset) { |
| + this.message = message; |
| + this.offset = offset; |
| + } |
| + |
| + Object.defineProperty(Validator.prototype, "offsetLimit", { |
| + get: function() { return this.message.buffer.byteLength; } |
| + }); |
| + |
| + Validator.prototype.claimMemory = function(numBytes) { |
| + if (numBytes < 0 || this.offset + numBytes > this.offsetLimit) |
| + return false; |
| + this.offset += numBytes; |
| + return true; |
| + } |
| + |
| + Validator.prototype.validateStructHeader = |
| + function(offset, minNumBytes, minNumFields) { |
| + if (!codec.isAligned(offset)) |
| + return ValidationError.MISALIGNED_OBJECT; |
| + |
| + if (offset + codec.kStructHeaderSize > this.offsetLimit) |
| + return ValidationError.ILLEGAL_MEMORY_RANGE; |
| + |
| + var numBytes = this.message.buffer.getUint32(offset); |
| + var numFields = this.message.buffer.getUint32(offset + 4); |
| + |
| + if (numBytes < minNumBytes || numFields < minNumFields) |
| + return ValidationError.UNEXPECTED_STRUCT_HEADER; |
| + |
| + if (!this.claimMemory(numBytes)) |
| + return ValidationError.ILLEGAL_MEMORY_RANGE; |
| + |
| + return ValidationError.NONE; |
| + } |
| + |
| + Validator.prototype.validateMessageHeader = function() { |
| + var numBytes = this.message.getHeaderNumBytes(); |
| + var numFields = this.message.getHeaderNumFields(); |
| + |
| + var validNumFieldsAndNumBytes = |
| + (numFields == 2 && numBytes == codec.kMessageHeaderSize) || |
|
Matt Perry
2014/07/28 23:59:03
indent += 2
hansmuller
2014/07/29 00:10:42
Done.
|
| + (numFields == 3 && numBytes == codec.kMessageWithRequestIDHeaderSize); |
| + if (!validNumFieldsAndNumBytes) |
| + return ValidationError.UNEXPECTED_STRUCT_HEADER; |
| + |
| + var expectsResponse = this.message.expectsResponse(); |
| + var isResponse = this.message.isResponse(); |
| + |
| + if (numFields == 2 && (expectsResponse || isResponse)) |
| + return ValidationError.MESSAGE_HEADER_MISSING_REQUEST_ID; |
| + |
| + if (isResponse && expectsResponse) |
| + return ValidationError.MESSAGE_HEADER_INVALID_FLAG_COMBINATION; |
| + |
| + return ValidationError.NONE; |
| + } |
| + |
| + Validator.prototype.validateMessage = function() { |
| + var err = this.validateStructHeader(0, codec.kStructHeaderSize, 2); |
| + if (err != ValidationError.NONE) |
| + return err; |
| + |
| + return this.validateMessageHeader(); |
| + } |
| + |
| + var exports = {}; |
| + exports.ValidationError = ValidationError; |
| + exports.Validator = Validator; |
| + return exports; |
| +}); |