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

Side by Side Diff: mojo/public/java/bindings/src/org/chromium/mojo/bindings/Encoder.java

Issue 524703004: Mojo: validate nullability in Java serialization. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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
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 package org.chromium.mojo.bindings; 5 package org.chromium.mojo.bindings;
6 6
7 import org.chromium.mojo.bindings.Struct.DataHeader; 7 import org.chromium.mojo.bindings.Struct.DataHeader;
8 import org.chromium.mojo.system.Core; 8 import org.chromium.mojo.system.Core;
9 import org.chromium.mojo.system.Handle; 9 import org.chromium.mojo.system.Handle;
10 import org.chromium.mojo.system.MessagePipeHandle; 10 import org.chromium.mojo.system.MessagePipeHandle;
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 /** 202 /**
203 * Encode a double at the given offset. 203 * Encode a double at the given offset.
204 */ 204 */
205 public void encode(double v, int offset) { 205 public void encode(double v, int offset) {
206 mEncoderState.byteBuffer.putDouble(mBaseOffset + offset, v); 206 mEncoderState.byteBuffer.putDouble(mBaseOffset + offset, v);
207 } 207 }
208 208
209 /** 209 /**
210 * Encode a {@link Struct} at the given offset. 210 * Encode a {@link Struct} at the given offset.
211 */ 211 */
212 public void encode(Struct v, int offset) { 212 public void encode(Struct v, int offset, boolean nullable) {
213 if (v == null) { 213 if (v == null) {
214 encodeNullPointer(offset); 214 encodeNullPointer(offset, nullable);
215 return; 215 return;
216 } 216 }
217 encodePointerToNextUnclaimedData(offset); 217 encodePointerToNextUnclaimedData(offset);
218 v.encode(this); 218 v.encode(this);
219 } 219 }
220 220
221 /** 221 /**
222 * Encodes a String. 222 * Encodes a String.
223 */ 223 */
224 public void encode(String v, int offset) { 224 public void encode(String v, int offset, boolean nullable) {
225 if (v == null) { 225 if (v == null) {
226 encodeNullPointer(offset); 226 encodeNullPointer(offset, nullable);
227 return; 227 return;
228 } 228 }
229 encode(v.getBytes( 229 final int arrayNullability = nullable ? BindingsHelper.ARRAY_NULLABLE : 0;
qsr 2014/09/02 07:41:44 You have a constant instead of this 0 in BindingsH
ppi 2014/09/02 16:50:43 Done.
230 Charset.forName("utf8")), offset, BindingsHelper.UNSPECIFIED_ARR AY_LENGTH); 230 encode(v.getBytes(Charset.forName("utf8")), offset, arrayNullability,
231 BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
231 } 232 }
232 233
233 /** 234 /**
234 * Encodes a {@link Handle}. 235 * Encodes a {@link Handle}.
235 */ 236 */
236 public void encode(Handle v, int offset) { 237 public void encode(Handle v, int offset, boolean nullable) {
237 if (v == null || !v.isValid()) { 238 if (v == null || !v.isValid()) {
ppi 2014/09/01 19:00:45 What do we do if the field is not nullable, v != n
qsr 2014/09/02 07:41:44 Non nullable for a handle means valid, so this cas
ppi 2014/09/02 16:50:43 Acknowledged.
238 encode(-1, offset); 239 encodeInvalidHandle(offset, nullable);
239 } else { 240 } else {
240 encode(mEncoderState.handles.size(), offset); 241 encode(mEncoderState.handles.size(), offset);
241 mEncoderState.handles.add(v); 242 mEncoderState.handles.add(v);
242 } 243 }
243 } 244 }
244 245
245 /** 246 /**
246 * Encode an {@link Interface}. 247 * Encode an {@link Interface}.
247 */ 248 */
248 public <T extends Interface> void encode(T v, int offset, Interface.Manager< T, ?> manager) { 249 public <T extends Interface> void encode(T v, int offset, boolean nullable,
250 Interface.Manager<T, ?> manager) {
249 if (v == null) { 251 if (v == null) {
250 encode(-1, offset); 252 encodeInvalidHandle(offset, nullable);
251 return; 253 return;
252 } 254 }
253 if (mEncoderState.core == null) { 255 if (mEncoderState.core == null) {
254 throw new UnsupportedOperationException( 256 throw new UnsupportedOperationException(
255 "The encoder has been created without a Core. It can't encod e an interface."); 257 "The encoder has been created without a Core. It can't encod e an interface.");
256 } 258 }
257 // If the instance is a proxy, pass the proxy's handle instead of creati ng a new stub. 259 // If the instance is a proxy, pass the proxy's handle instead of creati ng a new stub.
258 if (v instanceof Interface.AbstractProxy) { 260 if (v instanceof Interface.AbstractProxy) {
259 Interface.AbstractProxy proxy = (Interface.AbstractProxy) v; 261 Interface.AbstractProxy proxy = (Interface.AbstractProxy) v;
260 if (proxy.getMessageReceiver() instanceof HandleOwner) { 262 if (proxy.getMessageReceiver() instanceof HandleOwner) {
261 encode(((HandleOwner<?>) proxy.getMessageReceiver()).passHandle( ), offset); 263 encode(((HandleOwner<?>) proxy.getMessageReceiver()).passHandle( ), offset,
264 nullable);
262 return; 265 return;
263 } 266 }
264 // If the proxy is not over a message pipe, the default case applies . 267 // If the proxy is not over a message pipe, the default case applies .
265 } 268 }
266 Pair<MessagePipeHandle, MessagePipeHandle> handles = 269 Pair<MessagePipeHandle, MessagePipeHandle> handles =
267 mEncoderState.core.createMessagePipe(null); 270 mEncoderState.core.createMessagePipe(null);
268 manager.bind(v, handles.first); 271 manager.bind(v, handles.first);
269 encode(handles.second, offset); 272 encode(handles.second, offset, nullable);
270 } 273 }
271 274
272 /** 275 /**
273 * Encode an {@link InterfaceRequest}. 276 * Encode an {@link InterfaceRequest}.
274 */ 277 */
275 public <I extends Interface> void encode(InterfaceRequest<I> v, int offset) { 278 public <I extends Interface> void encode(InterfaceRequest<I> v, int offset, boolean nullable) {
276 if (v == null) { 279 if (v == null) {
277 encode(-1, offset); 280 encodeInvalidHandle(offset, nullable);
278 return; 281 return;
279 } 282 }
280 if (mEncoderState.core == null) { 283 if (mEncoderState.core == null) {
281 throw new UnsupportedOperationException( 284 throw new UnsupportedOperationException(
282 "The encoder has been created without a Core. It can't encod e an interface."); 285 "The encoder has been created without a Core. It can't encod e an interface.");
283 } 286 }
284 encode(v.passHandle(), offset); 287 encode(v.passHandle(), offset, nullable);
285 } 288 }
286 289
287 /** 290 /**
288 * Returns an {@link Encoder} suitable for encoding an array of pointer of t he given length. 291 * Returns an {@link Encoder} suitable for encoding an array of pointer of t he given length.
289 */ 292 */
290 public Encoder encodePointerArray(int length, int offset, int expectedLength ) { 293 public Encoder encodePointerArray(int length, int offset, int expectedLength ) {
291 return encoderForArray(BindingsHelper.POINTER_SIZE, length, offset, expe ctedLength); 294 return encoderForArray(BindingsHelper.POINTER_SIZE, length, offset, expe ctedLength);
292 } 295 }
293 296
294 /** 297 /**
295 * Encodes an array of booleans. 298 * Encodes an array of booleans.
296 */ 299 */
297 public void encode(boolean[] v, int offset, int expectedLength) { 300 public void encode(boolean[] v, int offset, int arrayNullability, int expect edLength) {
298 if (v == null) { 301 if (v == null) {
299 encodeNullPointer(offset); 302 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility));
300 return; 303 return;
301 } 304 }
302 if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH && 305 if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH &&
303 expectedLength != v.length) { 306 expectedLength != v.length) {
304 throw new SerializationException("Trying to encode a fixed array of incorrect length."); 307 throw new SerializationException("Trying to encode a fixed array of incorrect length.");
305 } 308 }
306 byte[] bytes = new byte[(v.length + 7) / BindingsHelper.ALIGNMENT]; 309 byte[] bytes = new byte[(v.length + 7) / BindingsHelper.ALIGNMENT];
307 for (int i = 0; i < bytes.length; ++i) { 310 for (int i = 0; i < bytes.length; ++i) {
308 for (int j = 0; j < BindingsHelper.ALIGNMENT; ++j) { 311 for (int j = 0; j < BindingsHelper.ALIGNMENT; ++j) {
309 int booleanIndex = BindingsHelper.ALIGNMENT * i + j; 312 int booleanIndex = BindingsHelper.ALIGNMENT * i + j;
310 if (booleanIndex < v.length && v[booleanIndex]) { 313 if (booleanIndex < v.length && v[booleanIndex]) {
311 bytes[i] |= (1 << j); 314 bytes[i] |= (1 << j);
312 } 315 }
313 } 316 }
314 } 317 }
315 encodeByteArray(bytes, v.length, offset); 318 encodeByteArray(bytes, v.length, offset);
316 } 319 }
317 320
318 /** 321 /**
319 * Encodes an array of bytes. 322 * Encodes an array of bytes.
320 */ 323 */
321 public void encode(byte[] v, int offset, int expectedLength) { 324 public void encode(byte[] v, int offset, int arrayNullability, int expectedL ength) {
322 if (v == null) { 325 if (v == null) {
323 encodeNullPointer(offset); 326 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility));
324 return; 327 return;
325 } 328 }
326 if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH && 329 if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH &&
327 expectedLength != v.length) { 330 expectedLength != v.length) {
328 throw new SerializationException("Trying to encode a fixed array of incorrect length."); 331 throw new SerializationException("Trying to encode a fixed array of incorrect length.");
329 } 332 }
330 encodeByteArray(v, v.length, offset); 333 encodeByteArray(v, v.length, offset);
331 } 334 }
332 335
333 /** 336 /**
334 * Encodes an array of shorts. 337 * Encodes an array of shorts.
335 */ 338 */
336 public void encode(short[] v, int offset, int expectedLength) { 339 public void encode(short[] v, int offset, int arrayNullability, int expected Length) {
337 if (v == null) { 340 if (v == null) {
338 encodeNullPointer(offset); 341 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility));
339 return; 342 return;
340 } 343 }
341 encoderForArray(2, v.length, offset, expectedLength).append(v); 344 encoderForArray(2, v.length, offset, expectedLength).append(v);
342 } 345 }
343 346
344 /** 347 /**
345 * Encodes an array of ints. 348 * Encodes an array of ints.
346 */ 349 */
347 public void encode(int[] v, int offset, int expectedLength) { 350 public void encode(int[] v, int offset, int arrayNullability, int expectedLe ngth) {
348 if (v == null) { 351 if (v == null) {
349 encodeNullPointer(offset); 352 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility));
350 return; 353 return;
351 } 354 }
352 encoderForArray(4, v.length, offset, expectedLength).append(v); 355 encoderForArray(4, v.length, offset, expectedLength).append(v);
353 } 356 }
354 357
355 /** 358 /**
356 * Encodes an array of floats. 359 * Encodes an array of floats.
357 */ 360 */
358 public void encode(float[] v, int offset, int expectedLength) { 361 public void encode(float[] v, int offset, int arrayNullability, int expected Length) {
359 if (v == null) { 362 if (v == null) {
360 encodeNullPointer(offset); 363 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility));
361 return; 364 return;
362 } 365 }
363 encoderForArray(4, v.length, offset, expectedLength).append(v); 366 encoderForArray(4, v.length, offset, expectedLength).append(v);
364 } 367 }
365 368
366 /** 369 /**
367 * Encodes an array of longs. 370 * Encodes an array of longs.
368 */ 371 */
369 public void encode(long[] v, int offset, int expectedLength) { 372 public void encode(long[] v, int offset, int arrayNullability, int expectedL ength) {
370 if (v == null) { 373 if (v == null) {
371 encodeNullPointer(offset); 374 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility));
372 return; 375 return;
373 } 376 }
374 encoderForArray(8, v.length, offset, expectedLength).append(v); 377 encoderForArray(8, v.length, offset, expectedLength).append(v);
375 } 378 }
376 379
377 /** 380 /**
378 * Encodes an array of doubles. 381 * Encodes an array of doubles.
379 */ 382 */
380 public void encode(double[] v, int offset, int expectedLength) { 383 public void encode(double[] v, int offset, int arrayNullability, int expecte dLength) {
381 if (v == null) { 384 if (v == null) {
382 encodeNullPointer(offset); 385 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility));
383 return; 386 return;
384 } 387 }
385 encoderForArray(8, v.length, offset, expectedLength).append(v); 388 encoderForArray(8, v.length, offset, expectedLength).append(v);
386 } 389 }
387 390
388 /** 391 /**
389 * Encodes an array of {@link Handle}. 392 * Encodes an array of {@link Handle}.
390 */ 393 */
391 public void encode(Handle[] v, int offset, int expectedLength) { 394 public void encode(Handle[] v, int offset, int arrayNullability, int expecte dLength) {
392 if (v == null) { 395 if (v == null) {
393 encodeNullPointer(offset); 396 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility));
394 return; 397 return;
395 } 398 }
396 Encoder e = encoderForArray( 399 Encoder e = encoderForArray(
397 BindingsHelper.SERIALIZED_HANDLE_SIZE, v.length, offset, expecte dLength); 400 BindingsHelper.SERIALIZED_HANDLE_SIZE, v.length, offset, expecte dLength);
398 for (int i = 0; i < v.length; ++i) { 401 for (int i = 0; i < v.length; ++i) {
399 e.encode(v[i], DataHeader.HEADER_SIZE + BindingsHelper.SERIALIZED_HA NDLE_SIZE * i); 402 e.encode(v[i], DataHeader.HEADER_SIZE + BindingsHelper.SERIALIZED_HA NDLE_SIZE * i,
403 BindingsHelper.isElementNullable(arrayNullability));
400 } 404 }
401 } 405 }
402 406
403 /** 407 /**
404 * Encodes an array of {@link Interface}. 408 * Encodes an array of {@link Interface}.
405 */ 409 */
406 public <T extends Interface> void encode(T[] v, int offset, int expectedLeng th, 410 public <T extends Interface> void encode(T[] v, int offset, int arrayNullabi lity,
407 Interface.Manager<T, ?> manager) { 411 int expectedLength, Interface.Manager<T, ?> manager) {
408 if (v == null) { 412 if (v == null) {
409 encodeNullPointer(offset); 413 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility));
410 return; 414 return;
411 } 415 }
412 Encoder e = encoderForArray( 416 Encoder e = encoderForArray(
413 BindingsHelper.SERIALIZED_HANDLE_SIZE, v.length, offset, expecte dLength); 417 BindingsHelper.SERIALIZED_HANDLE_SIZE, v.length, offset, expecte dLength);
414 for (int i = 0; i < v.length; ++i) { 418 for (int i = 0; i < v.length; ++i) {
415 e.encode(v[i], DataHeader.HEADER_SIZE + BindingsHelper.SERIALIZED_HA NDLE_SIZE * i, 419 e.encode(v[i], DataHeader.HEADER_SIZE + BindingsHelper.SERIALIZED_HA NDLE_SIZE * i,
416 manager); 420 BindingsHelper.isElementNullable(arrayNullability), manager) ;
417 } 421 }
418 } 422 }
419 423
420 /** 424 /**
421 * Encodes an array of {@link InterfaceRequest}. 425 * Encodes an array of {@link InterfaceRequest}.
422 */ 426 */
423 public <I extends Interface> void encode(InterfaceRequest<I>[] v, int offset , 427 public <I extends Interface> void encode(InterfaceRequest<I>[] v, int offset ,
424 int expectedLength) { 428 int arrayNullability, int expectedLength) {
425 if (v == null) { 429 if (v == null) {
426 encodeNullPointer(offset); 430 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility));
427 return; 431 return;
428 } 432 }
429 Encoder e = encoderForArray( 433 Encoder e = encoderForArray(
430 BindingsHelper.SERIALIZED_HANDLE_SIZE, v.length, offset, expecte dLength); 434 BindingsHelper.SERIALIZED_HANDLE_SIZE, v.length, offset, expecte dLength);
431 for (int i = 0; i < v.length; ++i) { 435 for (int i = 0; i < v.length; ++i) {
432 e.encode(v[i], DataHeader.HEADER_SIZE + BindingsHelper.SERIALIZED_HA NDLE_SIZE * i); 436 e.encode(v[i], DataHeader.HEADER_SIZE + BindingsHelper.SERIALIZED_HA NDLE_SIZE * i,
437 BindingsHelper.isElementNullable(arrayNullability));
433 } 438 }
434 } 439 }
435 440
436 /** 441 /**
437 * Encode a <code>null</code> pointer. 442 * Encodes a <code>null</code> pointer iff the object is nullable, raises an exception
443 * otherwise.
438 */ 444 */
439 public void encodeNullPointer(int offset) { 445 public void encodeNullPointer(int offset, boolean nullable) {
446 if (!nullable) {
447 throw new SerializationException(
448 "Trying to encode a null pointer for a non-nullable type.");
449 }
440 mEncoderState.byteBuffer.putLong(mBaseOffset + offset, 0); 450 mEncoderState.byteBuffer.putLong(mBaseOffset + offset, 0);
441 } 451 }
442 452
453 /**
454 * Encodes an invalid handle iff the object is nullable, raises an exception otherwise.
455 */
456 public void encodeInvalidHandle(int offset, boolean nullable) {
457 if (!nullable) {
458 throw new SerializationException(
459 "Trying to encode an invalid handle for a non-nullable type. ");
460 }
461 mEncoderState.byteBuffer.putInt(mBaseOffset + offset, -1);
462 }
463
443 private void encodePointerToNextUnclaimedData(int offset) { 464 private void encodePointerToNextUnclaimedData(int offset) {
444 encode((long) mEncoderState.dataEnd - (mBaseOffset + offset), offset); 465 encode((long) mEncoderState.dataEnd - (mBaseOffset + offset), offset);
445 } 466 }
446 467
447 private Encoder encoderForArray( 468 private Encoder encoderForArray(
448 int elementSizeInByte, int length, int offset, int expectedLength) { 469 int elementSizeInByte, int length, int offset, int expectedLength) {
449 if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH && 470 if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH &&
450 expectedLength != length) { 471 expectedLength != length) {
451 throw new SerializationException("Trying to encode a fixed array of incorrect length."); 472 throw new SerializationException("Trying to encode a fixed array of incorrect length.");
452 } 473 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 mEncoderState.byteBuffer.position(mBaseOffset + DataHeader.HEADER_SIZE); 508 mEncoderState.byteBuffer.position(mBaseOffset + DataHeader.HEADER_SIZE);
488 mEncoderState.byteBuffer.asDoubleBuffer().put(v); 509 mEncoderState.byteBuffer.asDoubleBuffer().put(v);
489 } 510 }
490 511
491 private void append(long[] v) { 512 private void append(long[] v) {
492 mEncoderState.byteBuffer.position(mBaseOffset + DataHeader.HEADER_SIZE); 513 mEncoderState.byteBuffer.position(mBaseOffset + DataHeader.HEADER_SIZE);
493 mEncoderState.byteBuffer.asLongBuffer().put(v); 514 mEncoderState.byteBuffer.asLongBuffer().put(v);
494 } 515 }
495 516
496 } 517 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698