diff options
author | Max Cai <maxtroy@google.com> | 2014-01-16 12:04:21 +0000 |
---|---|---|
committer | Max Cai <maxtroy@google.com> | 2014-01-16 12:41:26 +0000 |
commit | f4523ddb8a4e6f1008bfec2ee9e39629be792639 (patch) | |
tree | caafb95d8d88c96d22422fac3b878254e5e7eeb7 | |
parent | d888895a3b5cf764856d3a94ed526bf9994c1800 (diff) | |
download | external_protobuf-f4523ddb8a4e6f1008bfec2ee9e39629be792639.zip external_protobuf-f4523ddb8a4e6f1008bfec2ee9e39629be792639.tar.gz external_protobuf-f4523ddb8a4e6f1008bfec2ee9e39629be792639.tar.bz2 |
Fix repeated packed field merging code for non-packed data.
Enum fix is already included in the previous commit.
Bug: https://code.google.com/p/android/issues/detail?id=64893
Change-Id: I9fecff3c8822918a019028eb57fa39b361a2c960
-rw-r--r-- | java/src/test/java/com/google/protobuf/NanoTest.java | 20 | ||||
-rw-r--r-- | src/google/protobuf/compiler/javanano/javanano_primitive_field.cc | 5 |
2 files changed, 16 insertions, 9 deletions
diff --git a/java/src/test/java/com/google/protobuf/NanoTest.java b/java/src/test/java/com/google/protobuf/NanoTest.java index 2a56fa8..32a331e 100644 --- a/java/src/test/java/com/google/protobuf/NanoTest.java +++ b/java/src/test/java/com/google/protobuf/NanoTest.java @@ -3370,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}; @@ -3412,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)); } diff --git a/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc b/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc index 9898aaf..e044e89 100644 --- a/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc +++ b/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc @@ -261,6 +261,9 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, const Params param (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor)); (*variables)["tag_size"] = SimpleItoa( WireFormat::TagSize(descriptor->number(), descriptor->type())); + (*variables)["non_packed_tag"] = SimpleItoa( + internal::WireFormatLite::MakeTag(descriptor->number(), + internal::WireFormat::WireTypeForFieldType(descriptor->type()))); int fixed_size = FixedSize(descriptor->type()); if (fixed_size != -1) { (*variables)["fixed_size"] = SimpleItoa(fixed_size); @@ -748,7 +751,7 @@ GenerateMergingCode(io::Printer* printer) const { // First, figure out the length of the array, then parse. printer->Print(variables_, "int arrayLength = com.google.protobuf.nano.WireFormatNano\n" - " .getRepeatedFieldArrayLength(input, $tag$);\n" + " .getRepeatedFieldArrayLength(input, $non_packed_tag$);\n" "int i = this.$name$ == null ? 0 : this.$name$.length;\n"); if (GetJavaType(descriptor_) == JAVATYPE_BYTES) { |