proto: add tests for unmarshalling invalid field numbers

This change adds tests for unmarshalling fields with various invalid field
numbers. Our current behavior is that proto.Unmarshal will return an error when
it sees zero and larger than max field numbers and return nil for reserved
ones, which matches the C++ behavior. (Note: depending on which parser helper
in the C++ implementation, one may need to call additional method to check the
result, which we don't have in Go)

Change-Id: I8791fd077f25656107556f5606d55d05c1b4a120
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/191459
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
This commit is contained in:
Tuo Shan 2019-08-22 18:52:43 -07:00
parent 08ff730048
commit 6e25d8c6a6

View File

@ -134,6 +134,20 @@ func TestDecodeOneofNilWrapper(t *testing.T) {
}
}
func TestDecodeInvalidFieldNumbers(t *testing.T) {
for _, test := range invalidFieldNumberTestProtos {
t.Run(test.desc, func(t *testing.T) {
decoded := new(testpb.TestAllTypes) // type doesn't matter since we expect errors
err := proto.Unmarshal(test.wire, decoded)
if err == nil && !test.allowed {
t.Error("unmarshal: got nil want error")
} else if err != nil && test.allowed {
t.Errorf("unmarshal: got %v want nil since %s is allowed by Unmarshal", err, test.desc)
}
})
}
}
var testProtos = []testProto{
{
desc: "basic scalar types",
@ -1663,6 +1677,55 @@ var messageInfo_TestNoEnforceUTF8 = protoimpl.MessageInfo{
},
}
var invalidFieldNumberTestProtos = []struct {
desc string
wire []byte
allowed bool
}{
{
desc: "zero",
wire: pack.Message{
pack.Tag{pack.MinValidNumber - 1, pack.VarintType}, pack.Varint(1001),
}.Marshal(),
},
{
desc: "zero and one",
wire: pack.Message{
pack.Tag{pack.MinValidNumber - 1, pack.VarintType}, pack.Varint(1002),
pack.Tag{pack.MinValidNumber, pack.VarintType}, pack.Varint(1003),
}.Marshal(),
},
{
desc: "first reserved",
wire: pack.Message{
pack.Tag{pack.FirstReservedNumber, pack.VarintType}, pack.Varint(1004),
}.Marshal(),
allowed: true,
},
{
desc: "last reserved",
wire: pack.Message{
pack.Tag{pack.LastReservedNumber, pack.VarintType}, pack.Varint(1005),
}.Marshal(),
allowed: true,
},
{
desc: "max and max+1",
wire: pack.Message{
pack.Tag{pack.MaxValidNumber, pack.VarintType}, pack.Varint(1006),
pack.Tag{pack.MaxValidNumber + 1, pack.VarintType}, pack.Varint(1007),
}.Marshal(),
allowed: flags.ProtoLegacy,
},
{
desc: "max+1",
wire: pack.Message{
pack.Tag{pack.MaxValidNumber + 1, pack.VarintType}, pack.Varint(1008),
}.Marshal(),
allowed: flags.ProtoLegacy,
},
}
func build(m proto.Message, opts ...buildOpt) proto.Message {
for _, opt := range opts {
opt(m)