diff options
Diffstat (limited to 'java/src/test/java/com/google/protobuf/NanoTest.java')
-rw-r--r-- | java/src/test/java/com/google/protobuf/NanoTest.java | 142 |
1 files changed, 134 insertions, 8 deletions
diff --git a/java/src/test/java/com/google/protobuf/NanoTest.java b/java/src/test/java/com/google/protobuf/NanoTest.java index 687bc16..32a331e 100644 --- a/java/src/test/java/com/google/protobuf/NanoTest.java +++ b/java/src/test/java/com/google/protobuf/NanoTest.java @@ -33,6 +33,8 @@ package com.google.protobuf; import com.google.protobuf.nano.CodedInputByteBufferNano; import com.google.protobuf.nano.EnumClassNanoMultiple; import com.google.protobuf.nano.EnumClassNanos; +import com.google.protobuf.nano.EnumValidity; +import com.google.protobuf.nano.EnumValidityAccessors; import com.google.protobuf.nano.Extensions; import com.google.protobuf.nano.Extensions.AnotherMessage; import com.google.protobuf.nano.Extensions.MessageWithGroup; @@ -2093,6 +2095,126 @@ public class NanoTest extends TestCase { } /** + * Tests that invalid enum values from the wire are not accepted. + */ + public void testNanoEnumValidity() throws Exception { + final int invalid = 120; + final int alsoInvalid = 121; + + EnumValidity.M m = new EnumValidity.M(); + // Sanity check & baseline of the assertions for the first case below. + assertEquals(EnumValidity.E.default_, m.optionalE); + assertEquals(EnumValidity.E.BAZ, m.defaultE); + + m.optionalE = invalid; + m.defaultE = invalid; + // E contains all valid values + m.repeatedE = new int[] {EnumValidity.E.FOO, EnumValidity.E.BAR}; + m.packedE = new int[] {EnumValidity.E.FOO, EnumValidity.E.BAZ}; + // E2 contains some invalid values + m.repeatedE2 = new int[] {invalid, EnumValidity.E.BAR, alsoInvalid}; + m.packedE2 = new int[] {EnumValidity.E.FOO, invalid, alsoInvalid}; + // E3 contains all invalid values + m.repeatedE3 = new int[] {invalid, invalid}; + m.packedE3 = new int[] {alsoInvalid, alsoInvalid}; + byte[] serialized = MessageNano.toByteArray(m); + // Sanity check that we do have all data in the byte array. + assertEquals(31, serialized.length); + + // Test 1: tests that invalid values aren't included in the deserialized message. + EnumValidity.M deserialized = MessageNano.mergeFrom(new EnumValidity.M(), serialized); + assertEquals(EnumValidity.E.default_, deserialized.optionalE); + assertEquals(EnumValidity.E.BAZ, deserialized.defaultE); + assertTrue(Arrays.equals( + new int[] {EnumValidity.E.FOO, EnumValidity.E.BAR}, deserialized.repeatedE)); + assertTrue(Arrays.equals( + new int[] {EnumValidity.E.FOO, EnumValidity.E.BAZ}, deserialized.packedE)); + assertTrue(Arrays.equals( + new int[] {EnumValidity.E.BAR}, deserialized.repeatedE2)); + assertTrue(Arrays.equals( + new int[] {EnumValidity.E.FOO}, deserialized.packedE2)); + assertEquals(0, deserialized.repeatedE3.length); + assertEquals(0, deserialized.packedE3.length); + + // Test 2: tests that invalid values do not override previous values in the field, including + // arrays, including pre-existing invalid values. + deserialized.optionalE = EnumValidity.E.BAR; + deserialized.defaultE = alsoInvalid; + deserialized.repeatedE = new int[] {EnumValidity.E.BAZ}; + deserialized.packedE = new int[] {EnumValidity.E.BAZ, alsoInvalid}; + deserialized.repeatedE2 = new int[] {invalid, alsoInvalid}; + deserialized.packedE2 = null; + deserialized.repeatedE3 = null; + deserialized.packedE3 = new int[0]; + MessageNano.mergeFrom(deserialized, serialized); + assertEquals(EnumValidity.E.BAR, deserialized.optionalE); + assertEquals(alsoInvalid, deserialized.defaultE); + assertTrue(Arrays.equals( + new int[] {EnumValidity.E.BAZ, /* + */ EnumValidity.E.FOO, EnumValidity.E.BAR}, + deserialized.repeatedE)); + assertTrue(Arrays.equals( + new int[] {EnumValidity.E.BAZ, alsoInvalid, /* + */ EnumValidity.E.FOO, EnumValidity.E.BAZ}, + deserialized.packedE)); + assertTrue(Arrays.equals( + new int[] {invalid, alsoInvalid, /* + */ EnumValidity.E.BAR}, + deserialized.repeatedE2)); + assertTrue(Arrays.equals( + new int[] {/* <null> + */ EnumValidity.E.FOO}, + deserialized.packedE2)); + assertNull(deserialized.repeatedE3); // null + all invalid == null + assertEquals(0, deserialized.packedE3.length); // empty + all invalid == empty + + // Test 3: reading by alternative forms + EnumValidity.Alt alt = MessageNano.mergeFrom(new EnumValidity.Alt(), serialized); + assertEquals(EnumValidity.E.BAR, // last valid value in m.repeatedE2 + alt.repeatedE2AsOptional); + assertTrue(Arrays.equals(new int[] {EnumValidity.E.FOO}, alt.packedE2AsNonPacked)); + assertEquals(0, alt.nonPackedE3AsPacked.length); + } + + /** + * Tests the same as {@link #testNanoEnumValidity()} with accessor style. Repeated fields are + * not re-tested here because they are not affected by the accessor style. + */ + public void testNanoEnumValidityAccessors() throws Exception { + final int invalid = 120; + final int alsoInvalid = 121; + + EnumValidityAccessors.M m = new EnumValidityAccessors.M(); + // Sanity check & baseline of the assertions for the first case below. + assertEquals(EnumValidityAccessors.default_, m.getOptionalE()); + assertEquals(EnumValidityAccessors.BAZ, m.getDefaultE()); + + m.setOptionalE(invalid); + m.setDefaultE(invalid); + // Set repeatedE2 for Alt.repeatedE2AsOptional + m.repeatedE2 = new int[] {invalid, EnumValidityAccessors.BAR, alsoInvalid}; + byte[] serialized = MessageNano.toByteArray(m); + // Sanity check that we do have all data in the byte array. + assertEquals(10, serialized.length); + + // Test 1: tests that invalid values aren't included in the deserialized message. + EnumValidityAccessors.M deserialized = + MessageNano.mergeFrom(new EnumValidityAccessors.M(), serialized); + assertEquals(EnumValidityAccessors.default_, deserialized.getOptionalE()); + assertEquals(EnumValidityAccessors.BAZ, deserialized.getDefaultE()); + + // Test 2: tests that invalid values do not override previous values in the field, including + // pre-existing invalid values. + deserialized.setOptionalE(EnumValidityAccessors.BAR); + deserialized.setDefaultE(alsoInvalid); + MessageNano.mergeFrom(deserialized, serialized); + assertEquals(EnumValidityAccessors.BAR, deserialized.getOptionalE()); + assertEquals(alsoInvalid, deserialized.getDefaultE()); + + // Test 3: reading by alternative forms + EnumValidityAccessors.Alt alt = + MessageNano.mergeFrom(new EnumValidityAccessors.Alt(), serialized); + assertEquals(EnumValidityAccessors.BAR, // last valid value in m.repeatedE2 + alt.getRepeatedE2AsOptional()); + } + + /** * Tests that code generation correctly wraps a single message into its outer * class. The class {@code SingleMessageNano} is imported from the outer * class {@code UnittestSingleNano}, whose name is implicit. Any error would @@ -3248,12 +3370,16 @@ public class NanoTest extends TestCase { // Check that repeated fields with packable types can accept both packed and unpacked // serialized forms. NanoRepeatedPackables.NonPacked nonPacked = new NanoRepeatedPackables.NonPacked(); - nonPacked.int32S = new int[] {1, 2, 3}; - nonPacked.int64S = new long[] {4, 5, 6}; - nonPacked.uint32S = new int[] {7, 8, 9}; - nonPacked.uint64S = new long[] {10, 11, 12}; - nonPacked.sint32S = new int[] {13, 14, 15}; - nonPacked.sint64S = new long[] {16, 17, 18}; + // Exaggerates the first values of varint-typed arrays. This is to test that the parsing code + // of packed fields handles non-packed data correctly. If the code incorrectly thinks it is + // reading from a packed tag, it will read the first value as the byte length of the field, + // and the large number will cause the input to go out of bounds, thus capturing the error. + nonPacked.int32S = new int[] {1000, 2, 3}; + nonPacked.int64S = new long[] {4000, 5, 6}; + nonPacked.uint32S = new int[] {7000, 8, 9}; + nonPacked.uint64S = new long[] {10000, 11, 12}; + nonPacked.sint32S = new int[] {13000, 14, 15}; + nonPacked.sint64S = new long[] {16000, 17, 18}; nonPacked.fixed32S = new int[] {19, 20, 21}; nonPacked.fixed64S = new long[] {22, 23, 24}; nonPacked.sfixed32S = new int[] {25, 26, 27}; @@ -3290,8 +3416,8 @@ public class NanoTest extends TestCase { nonPacked = MessageNano.mergeFrom(new NanoRepeatedPackables.NonPacked(), mixedSerialized); packed = MessageNano.mergeFrom(new NanoRepeatedPackables.Packed(), mixedSerialized); assertRepeatedPackablesEqual(nonPacked, packed); - assertTrue(Arrays.equals(new int[] {1, 2, 3, 1, 2, 3}, nonPacked.int32S)); - assertTrue(Arrays.equals(new int[] {13, 14, 15, 13, 14, 15}, nonPacked.sint32S)); + assertTrue(Arrays.equals(new int[] {1000, 2, 3, 1000, 2, 3}, nonPacked.int32S)); + assertTrue(Arrays.equals(new int[] {13000, 14, 15, 13000, 14, 15}, nonPacked.sint32S)); assertTrue(Arrays.equals(new int[] {25, 26, 27, 25, 26, 27}, nonPacked.sfixed32S)); assertTrue(Arrays.equals(new boolean[] {false, true, false, true}, nonPacked.bools)); } |