summaryrefslogtreecommitdiffstats
path: root/mojo
diff options
context:
space:
mode:
Diffstat (limited to 'mojo')
-rw-r--r--mojo/android/javatests/AndroidManifest.xml3
-rw-r--r--mojo/android/javatests/src/org/chromium/mojo/bindings/BindingsTestUtils.java6
-rw-r--r--mojo/android/javatests/src/org/chromium/mojo/bindings/ValidationTest.java195
-rw-r--r--mojo/android/javatests/src/org/chromium/mojo/bindings/test/mojom/mojo/IntegrationTestInterface2TestHelper.java31
-rw-r--r--mojo/public/cpp/bindings/tests/validation_unittest.cc9
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/not_implemented_mthd0_struct_num_fields_less_than_min_requirement.data (renamed from mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd0_struct_num_fields_less_than_min_requirement.data)0
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/not_implemented_mthd0_struct_num_fields_less_than_min_requirement.expected (renamed from mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd0_struct_num_fields_less_than_min_requirement.expected)0
-rw-r--r--mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java102
-rw-r--r--mojo/public/java/bindings/src/org/chromium/mojo/bindings/MessageReceiver.java4
-rw-r--r--mojo/public/js/bindings/validation_unittests.js5
-rw-r--r--mojo/public/tools/bindings/generators/java_templates/struct_definition.tmpl2
11 files changed, 323 insertions, 34 deletions
diff --git a/mojo/android/javatests/AndroidManifest.xml b/mojo/android/javatests/AndroidManifest.xml
index 192aef7..290a1de 100644
--- a/mojo/android/javatests/AndroidManifest.xml
+++ b/mojo/android/javatests/AndroidManifest.xml
@@ -16,6 +16,7 @@
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="org.chromium.mojo.tests"
android:label="Tests for org.chromium.mojo"/>
- <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" />
<uses-permission android:name="android.permission.INJECT_EVENTS" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" />
</manifest>
diff --git a/mojo/android/javatests/src/org/chromium/mojo/bindings/BindingsTestUtils.java b/mojo/android/javatests/src/org/chromium/mojo/bindings/BindingsTestUtils.java
index bb0cd2b..6402767 100644
--- a/mojo/android/javatests/src/org/chromium/mojo/bindings/BindingsTestUtils.java
+++ b/mojo/android/javatests/src/org/chromium/mojo/bindings/BindingsTestUtils.java
@@ -80,9 +80,9 @@ public class BindingsTestUtils {
}
/**
- * Creates a new valid {@link MessageWithHeader}.
+ * Creates a new valid {@link Message}. The message will have a valid header.
*/
- public static MessageWithHeader newRandomMessageWithHeader(int size) {
+ public static Message newRandomMessageWithHeader(int size) {
assert size > 16;
ByteBuffer message = TestUtils.newRandomBuffer(size);
int[] headerAsInts = { 16, 2, 0, 0 };
@@ -90,6 +90,6 @@ public class BindingsTestUtils {
message.putInt(4 * i, headerAsInts[i]);
}
message.position(0);
- return new SimpleMessage(message, new ArrayList<Handle>()).asMojoMessage();
+ return new SimpleMessage(message, new ArrayList<Handle>());
}
}
diff --git a/mojo/android/javatests/src/org/chromium/mojo/bindings/ValidationTest.java b/mojo/android/javatests/src/org/chromium/mojo/bindings/ValidationTest.java
new file mode 100644
index 0000000..1abb40d
--- /dev/null
+++ b/mojo/android/javatests/src/org/chromium/mojo/bindings/ValidationTest.java
@@ -0,0 +1,195 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.mojo.bindings;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+import org.chromium.base.test.util.UrlUtils;
+import org.chromium.mojo.MojoTestCase;
+import org.chromium.mojo.bindings.test.mojom.mojo.ConformanceTestInterface;
+import org.chromium.mojo.bindings.test.mojom.mojo.IntegrationTestInterface1;
+import org.chromium.mojo.bindings.test.mojom.mojo.IntegrationTestInterface2TestHelper;
+import org.chromium.mojo.system.Handle;
+import org.chromium.mojo.system.InvalidHandle;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+
+/**
+ * Testing validation upon deserialization using the interfaces defined in the
+ * mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom file.
+ * <p>
+ * One needs to pass '--test_data=bindings:{path to mojo/public/interfaces/bindings/tests/data}' to
+ * the test_runner script for this test to find the validation data it needs.
+ */
+public class ValidationTest extends MojoTestCase {
+
+ /**
+ * The path where validation test data is.
+ */
+ private static final File VALIDATION_TEST_DATA_PATH =
+ new File(UrlUtils.getTestFilePath("bindings/validation"));
+
+ /**
+ * The data needed for a validation test.
+ */
+ private static class TestData {
+ public File dataFile;
+ public ValidationTestUtil.Data inputData;
+ public String expectedResult;
+ }
+
+ private static class DataFileFilter implements FileFilter {
+ private final String mPrefix;
+
+ public DataFileFilter(String prefix) {
+ this.mPrefix = prefix;
+ }
+
+ @Override
+ public boolean accept(File pathname) {
+ return pathname.isFile() && pathname.getName().startsWith(mPrefix)
+ && pathname.getName().endsWith(".data");
+ }
+ }
+
+ private static String getStringContent(File f) throws FileNotFoundException {
+ Scanner scanner = new Scanner(f).useDelimiter("\\Z");
+ if (scanner.hasNext()) {
+ return scanner.next();
+ }
+ return "";
+ }
+
+ private static List<TestData> getTestData(String prefix)
+ throws FileNotFoundException {
+ List<TestData> results = new ArrayList<TestData>();
+
+ // Do not fail if the test data is not present.
+ if (!VALIDATION_TEST_DATA_PATH.isDirectory()) {
+ Log.w("ValidationTest", "No test found.");
+ return results;
+ }
+
+ for (File dataFile : VALIDATION_TEST_DATA_PATH.listFiles(new DataFileFilter(prefix))) {
+ File resultFile = new File(dataFile.getParent(),
+ dataFile.getName().replaceFirst("\\.data$", ".expected"));
+ TestData testData = new TestData();
+ testData.dataFile = dataFile;
+ testData.inputData = ValidationTestUtil.parseData(getStringContent(dataFile));
+ testData.expectedResult = getStringContent(resultFile);
+ results.add(testData);
+ }
+ return results;
+ }
+
+ /**
+ * Runs all the test with the given prefix on the given {@link MessageReceiver}.
+ */
+ private static void runTest(String prefix, MessageReceiver messageReceiver)
+ throws FileNotFoundException {
+ List<TestData> testData = getTestData(prefix);
+ for (TestData test : testData) {
+ assertNull(test.inputData.getErrorMessage());
+ List<Handle> handles = new ArrayList<Handle>();
+ for (int i = 0; i < test.inputData.getHandlesCount(); ++i) {
+ handles.add(InvalidHandle.INSTANCE);
+ }
+ Message message = new SimpleMessage(test.inputData.getData(), handles);
+ boolean passed = messageReceiver.accept(message);
+ if (passed && !test.expectedResult.equals("PASS")) {
+ fail("Input: " + test.dataFile.getName() +
+ ": The message should have been refused. Expected error: " +
+ test.expectedResult);
+ }
+ if (!passed && test.expectedResult.equals("PASS")) {
+ fail("Input: " + test.dataFile.getName() +
+ ": The message should have been accepted.");
+ }
+ }
+ }
+
+ private static class RoutingMessageReceiver implements MessageReceiver {
+ private final MessageReceiver mRequest;
+ private final MessageReceiver mResponse;
+
+ private RoutingMessageReceiver(MessageReceiver request, MessageReceiver response) {
+ this.mRequest = request;
+ this.mResponse = response;
+ }
+
+ /**
+ * @see MessageReceiver#accept(Message)
+ */
+ @Override
+ public boolean accept(Message message) {
+ try {
+ MessageHeader header = message.asMojoMessage().getHeader();
+ if (header.hasFlag(MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
+ return mResponse.accept(message);
+ } else {
+ return mRequest.accept(message);
+ }
+ } catch (DeserializationException e) {
+ return false;
+ }
+ }
+
+ /**
+ * @see MessageReceiver#close()
+ */
+ @Override
+ public void close() {
+ }
+
+ }
+
+ /**
+ * A trivial message receiver that refuses all messages it receives.
+ */
+ private static class SinkMessageReceiver implements MessageReceiverWithResponder {
+
+ @Override
+ public boolean accept(Message message) {
+ return false;
+ }
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public boolean acceptWithResponder(Message message, MessageReceiver responder) {
+ return false;
+ }
+ }
+
+ /**
+ * Testing the conformance suite.
+ */
+ @SmallTest
+ public void testConformance() throws FileNotFoundException {
+ runTest("conformance_", ConformanceTestInterface.MANAGER.buildStub(null,
+ ConformanceTestInterface.MANAGER.buildProxy(null, new SinkMessageReceiver())));
+ }
+
+ /**
+ * Testing the integration suite.
+ */
+ @SmallTest
+ public void testIntegration() throws FileNotFoundException {
+ runTest("integration_",
+ new RoutingMessageReceiver(IntegrationTestInterface1.MANAGER.buildStub(null,
+ IntegrationTestInterface1.MANAGER.buildProxy(null,
+ new SinkMessageReceiver())),
+ IntegrationTestInterface2TestHelper.
+ newIntegrationTestInterface2MethodCallback()));
+ }
+}
diff --git a/mojo/android/javatests/src/org/chromium/mojo/bindings/test/mojom/mojo/IntegrationTestInterface2TestHelper.java b/mojo/android/javatests/src/org/chromium/mojo/bindings/test/mojom/mojo/IntegrationTestInterface2TestHelper.java
new file mode 100644
index 0000000..2a2b6b8
--- /dev/null
+++ b/mojo/android/javatests/src/org/chromium/mojo/bindings/test/mojom/mojo/IntegrationTestInterface2TestHelper.java
@@ -0,0 +1,31 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.mojo.bindings.test.mojom.mojo;
+
+import org.chromium.mojo.bindings.MessageReceiver;
+import org.chromium.mojo.bindings.test.mojom.mojo.IntegrationTestInterface2.Method0Response;
+import org.chromium.mojo.bindings.test.mojom.mojo.IntegrationTestInterface2_Internal.IntegrationTestInterface2Method0ResponseParamsForwardToCallback;
+
+/**
+ * Helper class to access {@link IntegrationTestInterface2_Internal} package protected method for
+ * tests.
+ */
+public class IntegrationTestInterface2TestHelper {
+
+ private static final class SinkMethod0Response implements Method0Response {
+ @Override
+ public void call(byte[] arg1) {
+ }
+ }
+
+ /**
+ * Creates a new {@link MessageReceiver} to use for the callback of
+ * |IntegrationTestInterface2#method0(Method0Response)|.
+ */
+ public static MessageReceiver newIntegrationTestInterface2MethodCallback() {
+ return new IntegrationTestInterface2Method0ResponseParamsForwardToCallback(
+ new SinkMethod0Response());
+ }
+}
diff --git a/mojo/public/cpp/bindings/tests/validation_unittest.cc b/mojo/public/cpp/bindings/tests/validation_unittest.cc
index 6463a9e..35a3e52 100644
--- a/mojo/public/cpp/bindings/tests/validation_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/validation_unittest.cc
@@ -391,6 +391,15 @@ TEST_F(ValidationTest, Conformance) {
RunValidationTests("conformance_", validators.GetHead());
}
+TEST_F(ValidationTest, NotImplemented) {
+ DummyMessageReceiver dummy_receiver;
+ mojo::internal::FilterChain validators(&dummy_receiver);
+ validators.Append<mojo::internal::MessageHeaderValidator>();
+ validators.Append<ConformanceTestInterface::RequestValidator_>();
+
+ RunValidationTests("not_implemented_", validators.GetHead());
+}
+
TEST_F(ValidationIntegrationTest, InterfacePtr) {
// Test that InterfacePtr<X> applies the correct validators and they don't
// conflict with each other:
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd0_struct_num_fields_less_than_min_requirement.data b/mojo/public/interfaces/bindings/tests/data/validation/not_implemented_mthd0_struct_num_fields_less_than_min_requirement.data
index ffcafd3..ffcafd3 100644
--- a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd0_struct_num_fields_less_than_min_requirement.data
+++ b/mojo/public/interfaces/bindings/tests/data/validation/not_implemented_mthd0_struct_num_fields_less_than_min_requirement.data
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd0_struct_num_fields_less_than_min_requirement.expected b/mojo/public/interfaces/bindings/tests/data/validation/not_implemented_mthd0_struct_num_fields_less_than_min_requirement.expected
index 25aceee..25aceee 100644
--- a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd0_struct_num_fields_less_than_min_requirement.expected
+++ b/mojo/public/interfaces/bindings/tests/data/validation/not_implemented_mthd0_struct_num_fields_less_than_min_requirement.expected
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 740e64b..efb9842 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,15 @@ 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) {
+ throw new DeserializationException(
+ "Negative size. Unsigned integers are not valid for java.");
+ }
+ if (numFields < 0) {
+ throw new DeserializationException(
+ "Negative number of fields. Unsigned integers are not valid for java.");
+ }
+
// Claim the remaining memory.
mValidator.claimMemory(mBaseOffset + DataHeader.HEADER_SIZE, mBaseOffset + size);
DataHeader res = new DataHeader(size, numFields);
@@ -128,24 +137,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 checks if it is correct for an
+ * array 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 +156,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 +164,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 +172,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 +180,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 +188,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 +196,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 +228,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 +252,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 +267,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 +282,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 +297,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 +312,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 +327,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 +431,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 +450,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 +469,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 +488,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 +508,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 +528,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 +548,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 +571,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 +588,43 @@ public class Decoder {
private Decoder getDecoderAtPosition(int offset) {
return new Decoder(mMessage, mValidator, offset);
}
+
+ /**
+ * Deserializes a {@link DataHeader} at the given offset and checks if it is correct for an
+ * array 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.");
+ }
+ }
}
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/MessageReceiver.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/MessageReceiver.java
index ca8f430..4223297 100644
--- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/MessageReceiver.java
+++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/MessageReceiver.java
@@ -12,8 +12,8 @@ import java.io.Closeable;
public interface MessageReceiver extends Closeable {
/**
- * Receive a {@link MessageWithHeader}. The {@link MessageReceiver} is allowed to mutable the
- * message. Returns |true| if the message has been handled, |false| otherwise.
+ * Receive a {@link Message}. The {@link MessageReceiver} is allowed to mutate the message.
+ * Returns |true| if the message has been handled, |false| otherwise.
*/
boolean accept(Message message);
diff --git a/mojo/public/js/bindings/validation_unittests.js b/mojo/public/js/bindings/validation_unittests.js
index cfba116..2f0bf9d 100644
--- a/mojo/public/js/bindings/validation_unittests.js
+++ b/mojo/public/js/bindings/validation_unittests.js
@@ -230,6 +230,11 @@ define([
testInterface.ConformanceTestInterfaceStub.prototype.validator]);
}
+ function testNotImplementedMessageValidation() {
+ testMessageValidation("not_implemented_", [
+ testInterface.ConformanceTestInterfaceStub.prototype.validator]);
+ }
+
function testIntegrationMessageValidation() {
testMessageValidation("integration_", [
testInterface.IntegrationTestInterface1Stub.prototype.validator,
diff --git a/mojo/public/tools/bindings/generators/java_templates/struct_definition.tmpl b/mojo/public/tools/bindings/generators/java_templates/struct_definition.tmpl
index 63d3898..2fc4439 100644
--- a/mojo/public/tools/bindings/generators/java_templates/struct_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/java_templates/struct_definition.tmpl
@@ -34,7 +34,7 @@ org.chromium.mojo.bindings.Decoder decoder{{level+1}} = decoder{{level}}.readPoi
if (decoder{{level+1}} == null) {
{{variable}} = null;
} else {
- DataHeader si{{level+1}} = decoder{{level+1}}.readArrayDataHeader({{array_expected_length(kind)}});
+ DataHeader si{{level+1}} = decoder{{level+1}}.readDataHeaderForPointerArray({{array_expected_length(kind)}});
{{variable}} = {{kind|new_array('si'~(level+1)~'.numFields')}};
for (int i{{level+1}} = 0; i{{level+1}} < si{{level+1}}.numFields; ++i{{level+1}}) {
{{decode(variable~'[i'~(level+1)~']', kind.kind, 'DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i'~(level+1), 0, level+1)|indent(8)}}