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 740e64b507b122018a3004e8bdbaed6b4d78569c..259e34422c5da0c3c2b715f22ac1de34e48886d7 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 |
| @@ -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) { |
|
ppi
2014/09/02 13:57:40
nit: maybe splitting this into two with definite e
qsr
2014/09/02 14:15:23
Done.
|
| + throw new DeserializationException( |
| + "Negative size or number of fields. Unsigned integer are not valid for java."); |
|
ppi
2014/09/02 13:57:39
s/integer/integers/
qsr
2014/09/02 14:15:23
Done.
|
| + } |
| + |
| // Claim the remaining memory. |
| mValidator.claimMemory(mBaseOffset + DataHeader.HEADER_SIZE, mBaseOffset + size); |
| DataHeader res = new DataHeader(size, numFields); |
| @@ -128,24 +133,18 @@ 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 if it is correct for an array |
|
ppi
2014/09/02 13:57:40
s/check/checks/
qsr
2014/09/02 14:15:23
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) { |
| + validateBufferSize(offset, 1); |
| return mMessage.getData().get(mBaseOffset + offset); |
| } |
| @@ -153,6 +152,7 @@ public class Decoder { |
| * 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,6 +160,7 @@ public class Decoder { |
| * Deserializes a short at the given offset. |
| */ |
| public short readShort(int offset) { |
| + validateBufferSize(offset, 2); |
| return mMessage.getData().getShort(mBaseOffset + offset); |
| } |
| @@ -167,6 +168,7 @@ public class Decoder { |
| * Deserializes an int at the given offset. |
| */ |
| public int readInt(int offset) { |
| + validateBufferSize(offset, 4); |
| return mMessage.getData().getInt(mBaseOffset + offset); |
| } |
| @@ -174,6 +176,7 @@ public class Decoder { |
| * Deserializes a float at the given offset. |
| */ |
| public float readFloat(int offset) { |
| + validateBufferSize(offset, 4); |
| return mMessage.getData().getFloat(mBaseOffset + offset); |
| } |
| @@ -181,6 +184,7 @@ public class Decoder { |
| * Deserializes a long at the given offset. |
| */ |
| public long readLong(int offset) { |
| + validateBufferSize(offset, 8); |
| return mMessage.getData().getLong(mBaseOffset + offset); |
| } |
| @@ -188,6 +192,7 @@ public class Decoder { |
| * Deserializes a double at the given offset. |
| */ |
| public double readDouble(int offset) { |
| + validateBufferSize(offset, 8); |
| return mMessage.getData().getDouble(mBaseOffset + offset); |
| } |
| @@ -219,8 +224,8 @@ public class Decoder { |
| if (d == null) { |
| return null; |
| } |
| - DataHeader si = d.readArrayDataHeader(expectedLength); |
| - byte[] bytes = new byte[si.numFields + 7 / BindingsHelper.ALIGNMENT]; |
| + 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]; |
| @@ -243,7 +248,7 @@ 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.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| d.mMessage.getData().get(result); |
| @@ -258,7 +263,7 @@ 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.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| d.mMessage.getData().asShortBuffer().get(result); |
| @@ -273,7 +278,7 @@ 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.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| d.mMessage.getData().asIntBuffer().get(result); |
| @@ -288,7 +293,7 @@ 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.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| d.mMessage.getData().asFloatBuffer().get(result); |
| @@ -303,7 +308,7 @@ 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.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| d.mMessage.getData().asLongBuffer().get(result); |
| @@ -318,7 +323,7 @@ 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.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE); |
| d.mMessage.getData().asDoubleBuffer().get(result); |
| @@ -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) { |
| @@ -579,4 +584,43 @@ public class Decoder { |
| private Decoder getDecoderAtPosition(int offset) { |
| return new Decoder(mMessage, mValidator, offset); |
| } |
| + |
| + /** |
| + * Deserializes a {@link DataHeader} at the given offset and check if it is correct for an array |
|
ppi
2014/09/02 13:57:40
s/check/checks/
qsr
2014/09/02 14:15:23
Done.
|
| + * of 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."); |
| + } |
| + } |
| } |