Chromium Code Reviews| Index: mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java |
| diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java |
| index 8c69b9219e703314740b4baca1ce11627e1111c7..5e5f1d52d3715b4a03901700b3091ddee3e14c74 100644 |
| --- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java |
| +++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java |
| @@ -103,12 +103,12 @@ public class Decoder { |
| * @param message The message to decode. |
| */ |
| public Decoder(Message message) { |
| - this(message, new Validator(message.buffer.limit(), message.handles.size()), 0); |
| + this(message, new Validator(message.getData().limit(), message.getHandles().size()), 0); |
| } |
| private Decoder(Message message, Validator validator, int baseOffset) { |
| mMessage = message; |
| - mMessage.buffer.order(ByteOrder.nativeOrder()); |
| + mMessage.getData().order(ByteOrder.nativeOrder()); |
| mBaseOffset = baseOffset; |
| mValidator = validator; |
| } |
| @@ -121,6 +121,11 @@ public class Decoder { |
| mValidator.claimMemory(mBaseOffset, mBaseOffset + DataHeader.HEADER_SIZE); |
| int size = readInt(DataHeader.SIZE_OFFSET); |
| int numFields = readInt(DataHeader.NUM_FIELDS_OFFSET); |
| + if (size < 0 || numFields < 0) { |
| + throw new DeserializationException( |
| + "Negative size or number of fields. Unsigned integer are not valid for java."); |
| + } |
| + |
| // Claim the remaining memory. |
| mValidator.claimMemory(mBaseOffset + DataHeader.HEADER_SIZE, mBaseOffset + size); |
| DataHeader res = new DataHeader(size, numFields); |
| @@ -128,31 +133,26 @@ public class Decoder { |
| } |
| /** |
| - * Deserializes a {@link DataHeader} of an array at the given offset. |
| - * |
| - * @param expectedLength the expected length of the array. |
| + * Deserializes a {@link DataHeader} at the given offset and check it is correct for an array |
|
ppi
2014/09/02 13:07:45
s/check it is correct/checks if it is correct/
qsr
2014/09/02 13:28:54
Done.
|
| + * where element have the given size. |
| */ |
| - public DataHeader readArrayDataHeader(int expectedLength) { |
| - DataHeader dataHeader = readDataHeader(); |
| - if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH |
| - && dataHeader.numFields != expectedLength) { |
| - throw new DeserializationException("Incorrect array length. Expected: " + |
| - expectedLength + ", but got: " + dataHeader.numFields + "."); |
| - } |
| - return dataHeader; |
| + public DataHeader readDataHeaderForPointerArray(int expectedLength) { |
| + return readDataHeaderForArray(8, expectedLength); |
| } |
| /** |
| * Deserializes a byte at the given offset. |
| */ |
| public byte readByte(int offset) { |
| - return mMessage.buffer.get(mBaseOffset + offset); |
| + validateBufferSize(offset, 1); |
| + return mMessage.getData().get(mBaseOffset + offset); |
| } |
| /** |
| * Deserializes a boolean at the given offset, re-using any partially read byte. |
| */ |
| public boolean readBoolean(int offset, int bit) { |
| + validateBufferSize(offset, 1); |
| return (readByte(offset) & (1 << bit)) != 0; |
| } |
| @@ -160,35 +160,40 @@ public class Decoder { |
| * Deserializes a short at the given offset. |
| */ |
| public short readShort(int offset) { |
| - return mMessage.buffer.getShort(mBaseOffset + offset); |
| + validateBufferSize(offset, 2); |
| + return mMessage.getData().getShort(mBaseOffset + offset); |
| } |
| /** |
| * Deserializes an int at the given offset. |
| */ |
| public int readInt(int offset) { |
| - return mMessage.buffer.getInt(mBaseOffset + offset); |
| + validateBufferSize(offset, 4); |
| + return mMessage.getData().getInt(mBaseOffset + offset); |
| } |
| /** |
| * Deserializes a float at the given offset. |
| */ |
| public float readFloat(int offset) { |
| - return mMessage.buffer.getFloat(mBaseOffset + offset); |
| + validateBufferSize(offset, 4); |
| + return mMessage.getData().getFloat(mBaseOffset + offset); |
| } |
| /** |
| * Deserializes a long at the given offset. |
| */ |
| public long readLong(int offset) { |
| - return mMessage.buffer.getLong(mBaseOffset + offset); |
| + validateBufferSize(offset, 8); |
| + return mMessage.getData().getLong(mBaseOffset + offset); |
| } |
| /** |
| * Deserializes a double at the given offset. |
| */ |
| public double readDouble(int offset) { |
| - return mMessage.buffer.getDouble(mBaseOffset + offset); |
| + validateBufferSize(offset, 8); |
| + return mMessage.getData().getDouble(mBaseOffset + offset); |
| } |
| /** |
| @@ -219,10 +224,10 @@ public class Decoder { |
| if (d == null) { |
| return null; |
| } |
| - DataHeader si = d.readArrayDataHeader(expectedLength); |
| - byte[] bytes = new byte[si.numFields + 7 / BindingsHelper.ALIGNMENT]; |
| - d.mMessage.buffer.position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| - d.mMessage.buffer.get(bytes); |
| + DataHeader si = d.readDataHeaderForBooleanArray(expectedLength); |
| + byte[] bytes = new byte[(si.numFields + 7) / BindingsHelper.ALIGNMENT]; |
| + d.mMessage.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| + d.mMessage.getData().get(bytes); |
| boolean[] result = new boolean[si.numFields]; |
| for (int i = 0; i < bytes.length; ++i) { |
| for (int j = 0; j < BindingsHelper.ALIGNMENT; ++j) { |
| @@ -243,10 +248,10 @@ public class Decoder { |
| if (d == null) { |
| return null; |
| } |
| - DataHeader si = d.readArrayDataHeader(expectedLength); |
| + DataHeader si = d.readDataHeaderForArray(1, expectedLength); |
| byte[] result = new byte[si.numFields]; |
| - d.mMessage.buffer.position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| - d.mMessage.buffer.get(result); |
| + d.mMessage.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| + d.mMessage.getData().get(result); |
| return result; |
| } |
| @@ -258,10 +263,10 @@ public class Decoder { |
| if (d == null) { |
| return null; |
| } |
| - DataHeader si = d.readArrayDataHeader(expectedLength); |
| + DataHeader si = d.readDataHeaderForArray(2, expectedLength); |
| short[] result = new short[si.numFields]; |
| - d.mMessage.buffer.position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| - d.mMessage.buffer.asShortBuffer().get(result); |
| + d.mMessage.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| + d.mMessage.getData().asShortBuffer().get(result); |
| return result; |
| } |
| @@ -273,10 +278,10 @@ public class Decoder { |
| if (d == null) { |
| return null; |
| } |
| - DataHeader si = d.readArrayDataHeader(expectedLength); |
| + DataHeader si = d.readDataHeaderForArray(4, expectedLength); |
| int[] result = new int[si.numFields]; |
| - d.mMessage.buffer.position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| - d.mMessage.buffer.asIntBuffer().get(result); |
| + d.mMessage.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| + d.mMessage.getData().asIntBuffer().get(result); |
| return result; |
| } |
| @@ -288,10 +293,10 @@ public class Decoder { |
| if (d == null) { |
| return null; |
| } |
| - DataHeader si = d.readArrayDataHeader(expectedLength); |
| + DataHeader si = d.readDataHeaderForArray(4, expectedLength); |
| float[] result = new float[si.numFields]; |
| - d.mMessage.buffer.position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| - d.mMessage.buffer.asFloatBuffer().get(result); |
| + d.mMessage.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| + d.mMessage.getData().asFloatBuffer().get(result); |
| return result; |
| } |
| @@ -303,10 +308,10 @@ public class Decoder { |
| if (d == null) { |
| return null; |
| } |
| - DataHeader si = d.readArrayDataHeader(expectedLength); |
| + DataHeader si = d.readDataHeaderForArray(8, expectedLength); |
| long[] result = new long[si.numFields]; |
| - d.mMessage.buffer.position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| - d.mMessage.buffer.asLongBuffer().get(result); |
| + d.mMessage.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| + d.mMessage.getData().asLongBuffer().get(result); |
| return result; |
| } |
| @@ -318,10 +323,10 @@ public class Decoder { |
| if (d == null) { |
| return null; |
| } |
| - DataHeader si = d.readArrayDataHeader(expectedLength); |
| + DataHeader si = d.readDataHeaderForArray(8, expectedLength); |
| double[] result = new double[si.numFields]; |
| - d.mMessage.buffer.position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| - d.mMessage.buffer.asDoubleBuffer().get(result); |
| + d.mMessage.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| + d.mMessage.getData().asDoubleBuffer().get(result); |
| return result; |
| } |
| @@ -338,7 +343,7 @@ public class Decoder { |
| return InvalidHandle.INSTANCE; |
| } |
| mValidator.claimHandle(index); |
| - return mMessage.handles.get(index); |
| + return mMessage.getHandles().get(index); |
| } |
| /** |
| @@ -422,7 +427,7 @@ public class Decoder { |
| if (d == null) { |
| return null; |
| } |
| - DataHeader si = d.readArrayDataHeader(expectedLength); |
| + DataHeader si = d.readDataHeaderForArray(4, expectedLength); |
| Handle[] result = new Handle[si.numFields]; |
| for (int i = 0; i < result.length; ++i) { |
| result[i] = d.readHandle( |
| @@ -441,7 +446,7 @@ public class Decoder { |
| if (d == null) { |
| return null; |
| } |
| - DataHeader si = d.readArrayDataHeader(expectedLength); |
| + DataHeader si = d.readDataHeaderForArray(4, expectedLength); |
| UntypedHandle[] result = new UntypedHandle[si.numFields]; |
| for (int i = 0; i < result.length; ++i) { |
| result[i] = d.readUntypedHandle( |
| @@ -460,7 +465,7 @@ public class Decoder { |
| if (d == null) { |
| return null; |
| } |
| - DataHeader si = d.readArrayDataHeader(expectedLength); |
| + DataHeader si = d.readDataHeaderForArray(4, expectedLength); |
| DataPipe.ConsumerHandle[] result = new DataPipe.ConsumerHandle[si.numFields]; |
| for (int i = 0; i < result.length; ++i) { |
| result[i] = d.readConsumerHandle( |
| @@ -479,7 +484,7 @@ public class Decoder { |
| if (d == null) { |
| return null; |
| } |
| - DataHeader si = d.readArrayDataHeader(expectedLength); |
| + DataHeader si = d.readDataHeaderForArray(4, expectedLength); |
| DataPipe.ProducerHandle[] result = new DataPipe.ProducerHandle[si.numFields]; |
| for (int i = 0; i < result.length; ++i) { |
| result[i] = d.readProducerHandle( |
| @@ -499,7 +504,7 @@ public class Decoder { |
| if (d == null) { |
| return null; |
| } |
| - DataHeader si = d.readArrayDataHeader(expectedLength); |
| + DataHeader si = d.readDataHeaderForArray(4, expectedLength); |
| MessagePipeHandle[] result = new MessagePipeHandle[si.numFields]; |
| for (int i = 0; i < result.length; ++i) { |
| result[i] = d.readMessagePipeHandle( |
| @@ -519,7 +524,7 @@ public class Decoder { |
| if (d == null) { |
| return null; |
| } |
| - DataHeader si = d.readArrayDataHeader(expectedLength); |
| + DataHeader si = d.readDataHeaderForArray(4, expectedLength); |
| SharedBufferHandle[] result = new SharedBufferHandle[si.numFields]; |
| for (int i = 0; i < result.length; ++i) { |
| result[i] = d.readSharedBufferHandle( |
| @@ -539,7 +544,7 @@ public class Decoder { |
| if (d == null) { |
| return null; |
| } |
| - DataHeader si = d.readArrayDataHeader(expectedLength); |
| + DataHeader si = d.readDataHeaderForArray(4, expectedLength); |
| S[] result = manager.buildArray(si.numFields); |
| for (int i = 0; i < result.length; ++i) { |
| // This cast is necessary because java 6 doesn't handle wildcard correctly when using |
| @@ -562,7 +567,7 @@ public class Decoder { |
| if (d == null) { |
| return null; |
| } |
| - DataHeader si = d.readArrayDataHeader(expectedLength); |
| + DataHeader si = d.readDataHeaderForArray(4, expectedLength); |
| @SuppressWarnings("unchecked") |
| InterfaceRequest<I>[] result = new InterfaceRequest[si.numFields]; |
| for (int i = 0; i < result.length; ++i) { |
| @@ -580,4 +585,42 @@ public class Decoder { |
| return new Decoder(mMessage, mValidator, offset); |
| } |
| + /** |
| + * Deserializes a {@link DataHeader} at the given offset and check it is correct for an array of |
|
ppi
2014/09/02 13:07:45
s/check it is correct/checks if it is correct/
qsr
2014/09/02 13:28:54
Done.
|
| + * booleans. |
| + */ |
| + private DataHeader readDataHeaderForBooleanArray(int expectedLength) { |
| + DataHeader dataHeader = readDataHeader(); |
| + if (dataHeader.size < DataHeader.HEADER_SIZE + (dataHeader.numFields + 7) / 8) { |
| + throw new DeserializationException("Array header is incorrect."); |
| + } |
| + if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH |
| + && dataHeader.numFields != expectedLength) { |
| + throw new DeserializationException("Incorrect array length. Expected: " + |
| + expectedLength + ", but got: " + dataHeader.numFields + "."); |
| + } |
| + return dataHeader; |
| + } |
| + |
| + /** |
| + * Deserializes a {@link DataHeader} of an array at the given offset. |
| + */ |
| + private DataHeader readDataHeaderForArray(long elementSize, int expectedLength) { |
| + DataHeader dataHeader = readDataHeader(); |
| + if (dataHeader.size < (DataHeader.HEADER_SIZE + elementSize * dataHeader.numFields)) { |
| + throw new DeserializationException("Array header is incorrect."); |
| + } |
| + if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH |
| + && dataHeader.numFields != expectedLength) { |
| + throw new DeserializationException("Incorrect array length. Expected: " + |
| + expectedLength + ", but got: " + dataHeader.numFields + "."); |
| + } |
| + return dataHeader; |
| + } |
| + |
| + private void validateBufferSize(int offset, int size) { |
| + if (mMessage.getData().limit() < offset + size) { |
| + throw new DeserializationException("Buffer is smaller than expected."); |
| + } |
| + } |
| } |