Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1494)

Unified Diff: mojo/public/js/validator.js

Issue 2796253002: Associated Message Validation (Closed)
Patch Set: Validate payloadInterfaceIds before getting it. Use [0] for dimensions for validateArrayPointer. Ca… Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: mojo/public/js/validator.js
diff --git a/mojo/public/js/validator.js b/mojo/public/js/validator.js
index 283546d4f18803fc7fd75cb4c165ce4f2886c0d4..037f3f46440a79ec6f4387aea225f47d027fce8d 100644
--- a/mojo/public/js/validator.js
+++ b/mojo/public/js/validator.js
@@ -4,7 +4,8 @@
define("mojo/public/js/validator", [
"mojo/public/js/codec",
-], function(codec) {
+ "mojo/public/js/interface_types",
+], function(codec, types) {
var validationError = {
NONE: 'VALIDATION_ERROR_NONE',
@@ -16,6 +17,9 @@ define("mojo/public/js/validator", [
UNEXPECTED_INVALID_HANDLE: 'VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE',
ILLEGAL_POINTER: 'VALIDATION_ERROR_ILLEGAL_POINTER',
UNEXPECTED_NULL_POINTER: 'VALIDATION_ERROR_UNEXPECTED_NULL_POINTER',
+ ILLEGAL_INTERFACE_ID: 'VALIDATION_ERROR_ILLEGAL_INTERFACE_ID',
+ UNEXPECTED_INVALID_INTERFACE_ID:
+ 'VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID',
MESSAGE_HEADER_INVALID_FLAGS:
'VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS',
MESSAGE_HEADER_MISSING_REQUEST_ID:
@@ -93,6 +97,16 @@ define("mojo/public/js/validator", [
cls === codec.NullableInterfaceRequest;
}
+ function isAssociatedInterfaceClass(cls) {
+ return cls === codec.AssociatedInterfacePtrInfo ||
+ cls === codec.NullableAssociatedInterfacePtrInfo;
+ }
+
+ function isAssociatedInterfaceRequestClass(cls) {
+ return cls === codec.AssociatedInterfaceRequest ||
+ cls === codec.NullableAssociatedInterfaceRequest;
+ }
+
function isNullable(type) {
return type === codec.NullableString || type === codec.NullableHandle ||
type === codec.NullableInterface ||
@@ -105,16 +119,21 @@ define("mojo/public/js/validator", [
this.message = message;
this.offset = 0;
this.handleIndex = 0;
+ this.associatedEndpointHandleIndex = 0;
+ this.payloadInterfaceIds = null;
+ this.offsetLimit = this.message.buffer.byteLength;
}
- Object.defineProperty(Validator.prototype, "offsetLimit", {
- get: function() { return this.message.buffer.byteLength; }
- });
-
Object.defineProperty(Validator.prototype, "handleIndexLimit", {
get: function() { return this.message.handles.length; }
});
+ Object.defineProperty(Validator.prototype, "associatedHandleIndexLimit", {
+ get: function() {
+ return this.payloadInterfaceIds ? this.payloadInterfaceIds.length : 0;
+ }
+ });
+
// True if we can safely allocate a block of bytes from start to
// to start + numBytes.
Validator.prototype.isValidRange = function(start, numBytes) {
@@ -152,6 +171,21 @@ define("mojo/public/js/validator", [
return true;
};
+ Validator.prototype.claimAssociatedEndpointHandle = function(index) {
+ if (index === codec.kEncodedInvalidHandleValue) {
+ return true;
+ }
+
+ if (index < this.associatedEndpointHandleIndex ||
+ index >= this.associatedHandleIndexLimit) {
+ return false;
+ }
+
+ // This is safe because handle indices are uint32.
+ this.associatedEndpointHandleIndex = index + 1;
+ return true;
+ };
+
Validator.prototype.validateEnum = function(offset, enumClass) {
// Note: Assumes that enums are always 32 bits! But this matches
// mojom::generate::pack::PackedField::GetSizeForKind, so it should be okay.
@@ -172,6 +206,22 @@ define("mojo/public/js/validator", [
return validationError.NONE;
};
+ Validator.prototype.validateAssociatedEndpointHandle = function(offset,
+ nullable) {
+ var index = this.message.buffer.getUint32(offset);
+
+ if (index === codec.kEncodedInvalidHandleValue) {
+ return nullable ? validationError.NONE :
+ validationError.UNEXPECTED_INVALID_INTERFACE_ID;
+ }
+
+ if (!this.claimAssociatedEndpointHandle(index)) {
+ return validationError.ILLEGAL_INTERFACE_ID;
+ }
+
+ return validationError.NONE;
+ };
+
Validator.prototype.validateInterface = function(offset, nullable) {
return this.validateHandle(offset, nullable);
};
@@ -180,6 +230,16 @@ define("mojo/public/js/validator", [
return this.validateHandle(offset, nullable);
};
+ Validator.prototype.validateAssociatedInterface = function(offset,
+ nullable) {
+ return this.validateAssociatedEndpointHandle(offset, nullable);
+ };
+
+ Validator.prototype.validateAssociatedInterfaceRequest = function(
+ offset, nullable) {
+ return this.validateAssociatedEndpointHandle(offset, nullable);
+ };
+
Validator.prototype.validateStructHeader = function(offset, minNumBytes) {
if (!codec.isAligned(offset))
return validationError.MISALIGNED_OBJECT;
@@ -223,33 +283,64 @@ define("mojo/public/js/validator", [
return fieldVersion <= structVersion;
};
- // TODO(wangjimmy): Add support for v2 messages.
Validator.prototype.validateMessageHeader = function() {
-
- var err = this.validateStructHeader(0, codec.kMessageHeaderSize);
- if (err != validationError.NONE)
+ var err = this.validateStructHeader(0, codec.kMessageV0HeaderSize);
+ if (err != validationError.NONE) {
return err;
+ }
var numBytes = this.message.getHeaderNumBytes();
var version = this.message.getHeaderVersion();
var validVersionAndNumBytes =
- (version == 0 && numBytes == codec.kMessageHeaderSize) ||
- (version == 1 &&
- numBytes == codec.kMessageWithRequestIDHeaderSize) ||
- (version > 1 &&
- numBytes >= codec.kMessageWithRequestIDHeaderSize);
- if (!validVersionAndNumBytes)
+ (version == 0 && numBytes == codec.kMessageV0HeaderSize) ||
+ (version == 1 && numBytes == codec.kMessageV1HeaderSize) ||
+ (version == 2 && numBytes == codec.kMessageV2HeaderSize) ||
+ (version > 2 && numBytes >= codec.kMessageV2HeaderSize);
+
+ if (!validVersionAndNumBytes) {
return validationError.UNEXPECTED_STRUCT_HEADER;
+ }
var expectsResponse = this.message.expectsResponse();
var isResponse = this.message.isResponse();
- if (version == 0 && (expectsResponse || isResponse))
+ if (version == 0 && (expectsResponse || isResponse)) {
return validationError.MESSAGE_HEADER_MISSING_REQUEST_ID;
+ }
- if (isResponse && expectsResponse)
+ if (isResponse && expectsResponse) {
return validationError.MESSAGE_HEADER_INVALID_FLAGS;
+ }
+
+ if (version < 2) {
+ return validationError.NONE;
+ }
+
+ var err = this.validateArrayPointer(
+ codec.kMessagePayloadInterfaceIdsPointerOffset,
+ codec.Uint32.encodedSize, codec.Uint32, true, [0], 0);
+
+ if (err != validationError.NONE) {
+ return err;
+ }
+
+ this.payloadInterfaceIds = this.message.getPayloadInterfaceIds();
+ if (this.payloadInterfaceIds) {
+ for (var interfaceId of this.payloadInterfaceIds) {
+ if (!types.isValidInterfaceId(interfaceId) ||
+ types.isMasterInterfaceId(interfaceId)) {
+ return validationError.ILLEGAL_INTERFACE_ID;
+ }
+ }
+ }
+
+ // Set offset to the start of the payload and offsetLimit to the start of
+ // the payload interface Ids so that payload can be validated using the
+ // same messageValidator.
+ this.offset = this.message.getHeaderNumBytes();
+ this.offsetLimit = this.decodePointer(
+ codec.kMessagePayloadInterfaceIdsPointerOffset);
return validationError.NONE;
};
@@ -451,6 +542,12 @@ define("mojo/public/js/validator", [
if (isInterfaceRequestClass(elementType))
return this.validateInterfaceRequestElements(
elementsOffset, numElements, nullable);
+ if (isAssociatedInterfaceClass(elementType))
+ return this.validateAssociatedInterfaceElements(
+ elementsOffset, numElements, nullable);
+ if (isAssociatedInterfaceRequestClass(elementType))
+ return this.validateAssociatedInterfaceRequestElements(
+ elementsOffset, numElements, nullable);
if (isStringClass(elementType))
return this.validateArrayElements(
elementsOffset, numElements, codec.Uint8, nullable, [0], 0);
@@ -508,6 +605,33 @@ define("mojo/public/js/validator", [
return validationError.NONE;
};
+ Validator.prototype.validateAssociatedInterfaceElements =
+ function(offset, numElements, nullable) {
+ var elementSize = codec.AssociatedInterfacePtrInfo.prototype.encodedSize;
+ for (var i = 0; i < numElements; i++) {
+ var elementOffset = offset + i * elementSize;
+ var err = this.validateAssociatedInterface(elementOffset, nullable);
+ if (err != validationError.NONE) {
+ return err;
+ }
+ }
+ return validationError.NONE;
+ };
+
+ Validator.prototype.validateAssociatedInterfaceRequestElements =
+ function(offset, numElements, nullable) {
+ var elementSize = codec.AssociatedInterfaceRequest.encodedSize;
+ for (var i = 0; i < numElements; i++) {
+ var elementOffset = offset + i * elementSize;
+ var err = this.validateAssociatedInterfaceRequest(elementOffset,
+ nullable);
+ if (err != validationError.NONE) {
+ return err;
+ }
+ }
+ return validationError.NONE;
+ };
+
// The elementClass parameter is the element type of the element arrays.
Validator.prototype.validateArrayElements =
function(offset, numElements, elementClass, nullable,
« no previous file with comments | « mojo/public/js/tests/validation_unittest.js ('k') | mojo/public/tools/bindings/generators/js_templates/module.amd.tmpl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698