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

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

Issue 2893493002: Mojo JS bindings: update the new bindings with the associated interface feature. (Closed)
Patch Set: . Created 3 years, 7 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
« no previous file with comments | « mojo/public/js/new_bindings/router.js ('k') | third_party/WebKit/LayoutTests/TestExpectations » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/public/js/new_bindings/validator.js
diff --git a/mojo/public/js/new_bindings/validator.js b/mojo/public/js/new_bindings/validator.js
index 610112b58eb498c076a139708f1e4411c06c05a3..b43a65b4abfb3514893156aa6b4fe295da9d3b9c 100644
--- a/mojo/public/js/new_bindings/validator.js
+++ b/mojo/public/js/new_bindings/validator.js
@@ -15,6 +15,9 @@
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:
@@ -27,6 +30,49 @@
};
var NULL_MOJO_POINTER = "NULL_MOJO_POINTER";
+ var gValidationErrorObserver = null;
+
+ function reportValidationError(error) {
+ if (gValidationErrorObserver) {
+ gValidationErrorObserver.setLastError(error);
+ }
+ }
+
+ var ValidationErrorObserverForTesting = (function() {
+ function Observer() {
+ this.lastError = validationError.NONE;
+ this.callback = null;
+ }
+
+ Observer.prototype.setLastError = function(error) {
+ this.lastError = error;
+ if (this.callback) {
+ this.callback(error);
+ }
+ };
+
+ Observer.prototype.reset = function(error) {
+ this.lastError = validationError.NONE;
+ this.callback = null;
+ };
+
+ return {
+ getInstance: function() {
+ if (!gValidationErrorObserver) {
+ gValidationErrorObserver = new Observer();
+ }
+ return gValidationErrorObserver;
+ }
+ };
+ })();
+
+ function isTestingMode() {
+ return Boolean(gValidationErrorObserver);
+ }
+
+ function clearTestingMode() {
+ gValidationErrorObserver = null;
+ }
function isEnumClass(cls) {
return cls instanceof internal.Enum;
@@ -49,9 +95,21 @@
cls === internal.NullableInterfaceRequest;
}
+ function isAssociatedInterfaceClass(cls) {
+ return cls === internal.AssociatedInterfacePtrInfo ||
+ cls === internal.NullableAssociatedInterfacePtrInfo;
+ }
+
+ function isAssociatedInterfaceRequestClass(cls) {
+ return cls === internal.AssociatedInterfaceRequest ||
+ cls === internal.NullableAssociatedInterfaceRequest;
+ }
+
function isNullable(type) {
return type === internal.NullableString ||
type === internal.NullableHandle ||
+ type === internal.NullableAssociatedInterfacePtrInfo ||
+ type === internal.NullableAssociatedInterfaceRequest ||
type === internal.NullableInterface ||
type === internal.NullableInterfaceRequest ||
type instanceof internal.NullableArrayOf ||
@@ -62,16 +120,21 @@
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) {
@@ -109,6 +172,21 @@
return true;
};
+ Validator.prototype.claimAssociatedEndpointHandle = function(index) {
+ if (index === internal.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.
@@ -129,6 +207,22 @@
return validationError.NONE;
};
+ Validator.prototype.validateAssociatedEndpointHandle = function(offset,
+ nullable) {
+ var index = this.message.buffer.getUint32(offset);
+
+ if (index === internal.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);
};
@@ -137,6 +231,16 @@
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 (!internal.isAligned(offset))
return validationError.MISALIGNED_OBJECT;
@@ -181,31 +285,63 @@
};
Validator.prototype.validateMessageHeader = function() {
-
- var err = this.validateStructHeader(0, internal.kMessageHeaderSize);
- if (err != validationError.NONE)
+ var err = this.validateStructHeader(0, internal.kMessageV0HeaderSize);
+ if (err != validationError.NONE) {
return err;
+ }
var numBytes = this.message.getHeaderNumBytes();
var version = this.message.getHeaderVersion();
var validVersionAndNumBytes =
- (version == 0 && numBytes == internal.kMessageHeaderSize) ||
- (version == 1 &&
- numBytes == internal.kMessageWithRequestIDHeaderSize) ||
- (version > 1 &&
- numBytes >= internal.kMessageWithRequestIDHeaderSize);
- if (!validVersionAndNumBytes)
+ (version == 0 && numBytes == internal.kMessageV0HeaderSize) ||
+ (version == 1 && numBytes == internal.kMessageV1HeaderSize) ||
+ (version == 2 && numBytes == internal.kMessageV2HeaderSize) ||
+ (version > 2 && numBytes >= internal.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(
+ internal.kMessagePayloadInterfaceIdsPointerOffset,
+ internal.Uint32.encodedSize, internal.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 (!internal.isValidInterfaceId(interfaceId) ||
+ internal.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(
+ internal.kMessagePayloadInterfaceIdsPointerOffset);
return validationError.NONE;
};
@@ -323,7 +459,7 @@
validationError.NONE : validationError.UNEXPECTED_NULL_POINTER;
var mapEncodedSize = internal.kStructHeaderSize +
- internal.kMapStructPayloadSize;
+ internal.kMapStructPayloadSize;
var err = this.validateStructHeader(structOffset, mapEncodedSize);
if (err !== validationError.NONE)
return err;
@@ -408,6 +544,12 @@
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, internal.Uint8, nullable, [0], 0);
@@ -465,6 +607,33 @@
return validationError.NONE;
};
+ Validator.prototype.validateAssociatedInterfaceElements =
+ function(offset, numElements, nullable) {
+ var elementSize = internal.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 = internal.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,
@@ -508,4 +677,9 @@
internal.validationError = validationError;
internal.Validator = Validator;
+ internal.ValidationErrorObserverForTesting =
+ ValidationErrorObserverForTesting;
+ internal.reportValidationError = reportValidationError;
+ internal.isTestingMode = isTestingMode;
+ internal.clearTestingMode = clearTestingMode;
})();
« no previous file with comments | « mojo/public/js/new_bindings/router.js ('k') | third_party/WebKit/LayoutTests/TestExpectations » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698