reflect/protoreflect: remove nullability from repeated extension fields
Remove repeated extension fields from the set of nullable fields,
so that Has reports false and Range does not visit a a zero-length
repeated extension field.
This corrects a fuzzer-detected case where unmarshaling and remarshaling
a wire-format message could result in a semantic change. For a repeated
extension field in non-packed encoding, unmarshaling a packed
representation of the field would result in a message which Has the
extension. Remarshaling it would discard the the field.
Fixes golang.org/protobuf#975
Change-Id: Ie836559c93d218db5b5201742a3b8ebbaacf54ed
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/204897
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Reviewed-by: Joe Tsai <joetsai@google.com>
diff --git a/proto/decode_test.go b/proto/decode_test.go
index 10b3f95..a01da16 100644
--- a/proto/decode_test.go
+++ b/proto/decode_test.go
@@ -615,6 +615,30 @@
}.Marshal(),
},
{
+ desc: "basic repeated types (zero-length packed encoding)",
+ decodeTo: []proto.Message{
+ &testpb.TestAllTypes{},
+ &test3pb.TestAllTypes{},
+ &testpb.TestAllExtensions{},
+ },
+ wire: pack.Message{
+ pack.Tag{31, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{32, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{33, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{34, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{35, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{36, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{37, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{38, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{39, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{40, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{41, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{42, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{43, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{51, pack.BytesType}, pack.LengthPrefix{},
+ }.Marshal(),
+ },
+ {
desc: "packed repeated types",
decodeTo: []proto.Message{&testpb.TestPackedTypes{
PackedInt32: []int32{1001, 2001},
@@ -701,6 +725,29 @@
}.Marshal(),
},
{
+ desc: "packed repeated types (zero length)",
+ decodeTo: []proto.Message{
+ &testpb.TestPackedTypes{},
+ &testpb.TestPackedExtensions{},
+ },
+ wire: pack.Message{
+ pack.Tag{90, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{91, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{92, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{93, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{94, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{95, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{96, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{97, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{98, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{99, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{100, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{101, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{102, pack.BytesType}, pack.LengthPrefix{},
+ pack.Tag{103, pack.BytesType}, pack.LengthPrefix{},
+ }.Marshal(),
+ },
+ {
desc: "repeated messages",
decodeTo: []proto.Message{&testpb.TestAllTypes{
RepeatedNestedMessage: []*testpb.TestAllTypes_NestedMessage{