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

Side by Side Diff: mojo/public/js/bindings/validator.js

Issue 490623003: Add JS bindings validation logic for non-nullable types (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 define("mojo/public/js/bindings/validator", [ 5 define("mojo/public/js/bindings/validator", [
6 "mojo/public/js/bindings/codec", 6 "mojo/public/js/bindings/codec",
7 ], function(codec) { 7 ], function(codec) {
yzshen1 2014/08/20 17:04:20 I think the indent is a little unusual. Maybe the
hansmuller 2014/08/20 17:46:30 Done.
8 8
9 var validationError = { 9 var validationError = {
10 NONE: 'VALIDATION_ERROR_NONE', 10 NONE: 'VALIDATION_ERROR_NONE',
11 MISALIGNED_OBJECT: 'VALIDATION_ERROR_MISALIGNED_OBJECT', 11 MISALIGNED_OBJECT: 'VALIDATION_ERROR_MISALIGNED_OBJECT',
12 ILLEGAL_MEMORY_RANGE: 'VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE', 12 ILLEGAL_MEMORY_RANGE: 'VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE',
13 UNEXPECTED_STRUCT_HEADER: 'VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER', 13 UNEXPECTED_STRUCT_HEADER: 'VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER',
14 UNEXPECTED_ARRAY_HEADER: 'VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER', 14 UNEXPECTED_ARRAY_HEADER: 'VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER',
15 ILLEGAL_HANDLE: 'VALIDATION_ERROR_ILLEGAL_HANDLE', 15 ILLEGAL_HANDLE: 'VALIDATION_ERROR_ILLEGAL_HANDLE',
16 UNEXPECTED_INVALID_HANDLE: 'VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE',
16 ILLEGAL_POINTER: 'VALIDATION_ERROR_ILLEGAL_POINTER', 17 ILLEGAL_POINTER: 'VALIDATION_ERROR_ILLEGAL_POINTER',
18 UNEXPECTED_NULL_POINTER: 'VALIDATION_ERROR_UNEXPECTED_NULL_POINTER',
17 MESSAGE_HEADER_INVALID_FLAG_COMBINATION: 19 MESSAGE_HEADER_INVALID_FLAG_COMBINATION:
18 'VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINATION', 20 'VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINATION',
19 MESSAGE_HEADER_MISSING_REQUEST_ID: 21 MESSAGE_HEADER_MISSING_REQUEST_ID:
20 'VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID' 22 'VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID'
21 }; 23 };
22 24
23 var NULL_MOJO_POINTER = "NULL_MOJO_POINTER"; 25 var NULL_MOJO_POINTER = "NULL_MOJO_POINTER";
24 26
27 function isStringClass(cls) {
28 return cls === codec.String || cls === codec.NullableString;
29 }
30
31 function isHandleClass(cls) {
32 return cls === codec.Handle || cls === codec.NullableHandle;
33 }
34
35 function isNullable(type) {
36 return type === codec.NullableString || type === codec.NullableHandle ||
37 type instanceof codec.NullableArrayOf ||
yzshen1 2014/08/20 17:04:20 wrong indent. (37 - 39)
hansmuller 2014/08/20 17:46:31 Done.
38 type instanceof codec.NullablePointerTo;
39 }
40
25 function Validator(message) { 41 function Validator(message) {
26 this.message = message; 42 this.message = message;
27 this.offset = 0; 43 this.offset = 0;
28 this.handleIndex = 0; 44 this.handleIndex = 0;
29 } 45 }
30 46
31 Object.defineProperty(Validator.prototype, "offsetLimit", { 47 Object.defineProperty(Validator.prototype, "offsetLimit", {
32 get: function() { return this.message.buffer.byteLength; } 48 get: function() { return this.message.buffer.byteLength; }
33 }); 49 });
34 50
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 return true; 82 return true;
67 83
68 if (index < this.handleIndex || index >= this.handleIndexLimit) 84 if (index < this.handleIndex || index >= this.handleIndexLimit)
69 return false; 85 return false;
70 86
71 // This is safe because handle indices are uint32. 87 // This is safe because handle indices are uint32.
72 this.handleIndex = index + 1; 88 this.handleIndex = index + 1;
73 return true; 89 return true;
74 } 90 }
75 91
76 Validator.prototype.validateHandle = function(offset) { 92 Validator.prototype.validateHandle = function(offset, nullable) {
yzshen1 2014/08/20 17:04:20 One thing may worth considering: Passing nullable
hansmuller 2014/08/20 17:46:31 I don't know what the performance impact of an add
yzshen1 2014/08/20 17:54:08 Sounds good.
77 var index = this.message.buffer.getUint32(offset); 93 var index = this.message.buffer.getUint32(offset);
94
95 if (index === codec.kEncodedInvalidHandleValue)
96 return nullable ?
97 validationError.NONE : validationError.UNEXPECTED_INVALID_HANDLE;
98
78 if (!this.claimHandle(index)) 99 if (!this.claimHandle(index))
79 return validationError.ILLEGAL_HANDLE; 100 return validationError.ILLEGAL_HANDLE;
80 return validationError.NONE; 101 return validationError.NONE;
81 } 102 }
82 103
83 Validator.prototype.validateStructHeader = 104 Validator.prototype.validateStructHeader =
84 function(offset, minNumBytes, minNumFields) { 105 function(offset, minNumBytes, minNumFields) {
85 if (!codec.isAligned(offset)) 106 if (!codec.isAligned(offset))
86 return validationError.MISALIGNED_OBJECT; 107 return validationError.MISALIGNED_OBJECT;
87 108
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 // NULL_MOJO_POINTER if the pointer represents a null, or JS null if the 154 // NULL_MOJO_POINTER if the pointer represents a null, or JS null if the
134 // pointer's value is not valid. 155 // pointer's value is not valid.
135 Validator.prototype.decodePointer = function(offset) { 156 Validator.prototype.decodePointer = function(offset) {
136 var pointerValue = this.message.buffer.getUint64(offset); 157 var pointerValue = this.message.buffer.getUint64(offset);
137 if (pointerValue === 0) 158 if (pointerValue === 0)
138 return NULL_MOJO_POINTER; 159 return NULL_MOJO_POINTER;
139 var bufferOffset = offset + pointerValue; 160 var bufferOffset = offset + pointerValue;
140 return Number.isSafeInteger(bufferOffset) ? bufferOffset : null; 161 return Number.isSafeInteger(bufferOffset) ? bufferOffset : null;
141 } 162 }
142 163
143 Validator.prototype.validateArrayPointer = 164 Validator.prototype.validateArrayPointer = function(
144 function(offset, elementSize, expectedElementCount, elementType) { 165 offset, elementSize, expectedElementCount, elementType, nullable) {
145 var arrayOffset = this.decodePointer(offset); 166 var arrayOffset = this.decodePointer(offset);
146 if (arrayOffset === null) 167 if (arrayOffset === null)
147 return validationError.ILLEGAL_POINTER; 168 return validationError.ILLEGAL_POINTER;
169
148 if (arrayOffset === NULL_MOJO_POINTER) 170 if (arrayOffset === NULL_MOJO_POINTER)
149 return validationError.NONE; 171 return nullable ?
172 validationError.NONE : validationError.UNEXPECTED_NULL_POINTER;
173
150 return this.validateArray( 174 return this.validateArray(
151 arrayOffset, elementSize, expectedElementCount, elementType); 175 arrayOffset, elementSize, expectedElementCount, elementType);
152 } 176 }
153 177
154 Validator.prototype.validateStructPointer = function(offset, structClass) { 178 Validator.prototype.validateStructPointer = function(
179 offset, structClass, nullable) {
155 var structOffset = this.decodePointer(offset); 180 var structOffset = this.decodePointer(offset);
156 if (structOffset === null) 181 if (structOffset === null)
157 return validationError.ILLEGAL_POINTER; 182 return validationError.ILLEGAL_POINTER;
183
158 if (structOffset === NULL_MOJO_POINTER) 184 if (structOffset === NULL_MOJO_POINTER)
159 return validationError.NONE; 185 return nullable ?
186 validationError.NONE : validationError.UNEXPECTED_NULL_POINTER;
187
160 return structClass.validate(this, structOffset); 188 return structClass.validate(this, structOffset);
161 } 189 }
162 190
163 Validator.prototype.validateStringPointer = function(offset) { 191 Validator.prototype.validateStringPointer = function(offset) {
164 return this.validateArrayPointer( 192 return this.validateArrayPointer(
165 offset, codec.Uint8.encodedSize, 0, codec.Uint8); 193 offset, codec.Uint8.encodedSize, 0, codec.Uint8);
166 } 194 }
167 195
168 // Similar to Array_Data<T>::Validate() 196 // Similar to Array_Data<T>::Validate()
169 // mojo/public/cpp/bindings/lib/array_internal.h 197 // mojo/public/cpp/bindings/lib/array_internal.h
(...skipping 19 matching lines...) Expand all
189 217
190 if (expectedElementCount != 0 && numElements != expectedElementCount) 218 if (expectedElementCount != 0 && numElements != expectedElementCount)
191 return validationError.UNEXPECTED_ARRAY_HEADER; 219 return validationError.UNEXPECTED_ARRAY_HEADER;
192 220
193 if (!this.claimRange(offset, numBytes)) 221 if (!this.claimRange(offset, numBytes))
194 return validationError.ILLEGAL_MEMORY_RANGE; 222 return validationError.ILLEGAL_MEMORY_RANGE;
195 223
196 // Validate the array's elements if they are pointers or handles. 224 // Validate the array's elements if they are pointers or handles.
197 225
198 var elementsOffset = offset + codec.kArrayHeaderSize; 226 var elementsOffset = offset + codec.kArrayHeaderSize;
199 if (elementType === codec.Handle) 227 var nullable = isNullable(elementType);
200 return this.validateHandleElements(elementsOffset, numElements); 228
229 if (isHandleClass(elementType))
230 return this.validateHandleElements(elementsOffset, numElements, nullable);
231 if (isStringClass(elementType))
232 return this.validateArrayElements(
233 elementsOffset, numElements, codec.Uint8, nullable)
201 if (elementType instanceof codec.PointerTo) 234 if (elementType instanceof codec.PointerTo)
202 return this.validateStructElements( 235 return this.validateStructElements(
203 elementsOffset, numElements, elementType.cls); 236 elementsOffset, numElements, elementType.cls, nullable);
204 if (elementType instanceof codec.String)
205 return this.validateArrayElements(
206 elementsOffset, numElements, codec.Uint8);
207 if (elementType instanceof codec.ArrayOf) 237 if (elementType instanceof codec.ArrayOf)
208 return this.validateArrayElements( 238 return this.validateArrayElements(
209 elementsOffset, numElements, elementType.cls); 239 elementsOffset, numElements, elementType.cls, nullable);
210 240
211 return validationError.NONE; 241 return validationError.NONE;
212 } 242 }
213 243
214 // Note: the |offset + i * elementSize| computation in the validateFooElements 244 // Note: the |offset + i * elementSize| computation in the validateFooElements
215 // methods below is "safe" because elementSize <= 8, offset and 245 // methods below is "safe" because elementSize <= 8, offset and
216 // numElements are uint32, and 0 <= i < numElements. 246 // numElements are uint32, and 0 <= i < numElements.
217 247
218 Validator.prototype.validateHandleElements = function(offset, numElements) { 248 Validator.prototype.validateHandleElements =
249 function(offset, numElements, nullable) {
219 var elementSize = codec.Handle.encodedSize; 250 var elementSize = codec.Handle.encodedSize;
220 for (var i = 0; i < numElements; i++) { 251 for (var i = 0; i < numElements; i++) {
221 var index = this.message.buffer.getUint32(offset + i * elementSize); 252 var elementOffset = offset + i * elementSize;
222 if (!this.claimHandle(index)) 253 var err = this.validateHandle(elementOffset, nullable);
223 return validationError.ILLEGAL_HANDLE; 254 if (err != validationError.NONE)
255 return err;
224 } 256 }
225 return validationError.NONE; 257 return validationError.NONE;
226 } 258 }
227 259
228 // The elementClass parameter is the element type of the element arrays. 260 // The elementClass parameter is the element type of the element arrays.
229 Validator.prototype.validateArrayElements = 261 Validator.prototype.validateArrayElements =
230 function(offset, numElements, elementClass) { 262 function(offset, numElements, elementClass, nullable) {
231 var elementSize = codec.PointerTo.prototype.encodedSize; 263 var elementSize = codec.PointerTo.prototype.encodedSize;
232 for (var i = 0; i < numElements; i++) { 264 for (var i = 0; i < numElements; i++) {
233 var elementOffset = offset + i * elementSize; 265 var elementOffset = offset + i * elementSize;
234 var err = this.validateArrayPointer( 266 var err = this.validateArrayPointer(
235 elementOffset, elementClass.encodedSize, 0, elementClass); 267 elementOffset, elementClass.encodedSize, 0, elementClass, nullable);
yzshen1 2014/08/20 17:04:20 wrong indent.
hansmuller 2014/08/20 17:46:31 Done.
236 if (err != validationError.NONE) 268 if (err != validationError.NONE)
237 return err; 269 return err;
238 } 270 }
239 return validationError.NONE; 271 return validationError.NONE;
240 } 272 }
241 273
242 Validator.prototype.validateStructElements = 274 Validator.prototype.validateStructElements =
243 function(offset, numElements, structClass) { 275 function(offset, numElements, structClass, nullable) {
244 var elementSize = codec.PointerTo.prototype.encodedSize; 276 var elementSize = codec.PointerTo.prototype.encodedSize;
245 for (var i = 0; i < numElements; i++) { 277 for (var i = 0; i < numElements; i++) {
246 var elementOffset = offset + i * elementSize; 278 var elementOffset = offset + i * elementSize;
247 var err = this.validateStructPointer(elementOffset, structClass); 279 var err =
280 this.validateStructPointer(elementOffset, structClass, nullable);
248 if (err != validationError.NONE) 281 if (err != validationError.NONE)
249 return err; 282 return err;
250 } 283 }
251 return validationError.NONE; 284 return validationError.NONE;
252 } 285 }
253 286
254 var exports = {}; 287 var exports = {};
255 exports.validationError = validationError; 288 exports.validationError = validationError;
256 exports.Validator = Validator; 289 exports.Validator = Validator;
257 return exports; 290 return exports;
258 }); 291 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698