mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-03-30 07:20:48 +00:00
internal/encoding/messageset: fix decoding of some invalid data
For historical reasons, MessageSets items are allowed to have field numbers outside the usual valid range. Detect the case where the field number cannot fit in an int32 and report an error. Also check for a field number of 0 (always invalid). Handle the case where a MessageSet item includes an unknown field. We have no place to put the contents of the field, so drop it. This is, I believe, consistent with other implementations. Change-Id: Ic403427e1c276cbfa232ca577e7a799cce706bc7 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/221939 Reviewed-by: Herbie Ong <herbie@google.com>
This commit is contained in:
parent
969537aa29
commit
e1c61a307e
@ -6,6 +6,8 @@
|
||||
package messageset
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"google.golang.org/protobuf/internal/encoding/wire"
|
||||
"google.golang.org/protobuf/internal/errors"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
@ -146,6 +148,9 @@ func ConsumeFieldValue(b []byte, wantLen bool) (typeid wire.Number, message []by
|
||||
return 0, nil, 0, wire.ParseError(n)
|
||||
}
|
||||
b = b[n:]
|
||||
if v < 1 || v > math.MaxInt32 {
|
||||
return 0, nil, 0, errors.New("invalid type_id in message set")
|
||||
}
|
||||
typeid = wire.Number(v)
|
||||
case num == FieldMessage && wtyp == wire.BytesType:
|
||||
m, n := wire.ConsumeBytes(b)
|
||||
@ -178,6 +183,13 @@ func ConsumeFieldValue(b []byte, wantLen bool) (typeid wire.Number, message []by
|
||||
}
|
||||
}
|
||||
b = b[n:]
|
||||
default:
|
||||
// We have no place to put it, so we just ignore unknown fields.
|
||||
n := wire.ConsumeFieldValue(num, wtyp, b)
|
||||
if n < 0 {
|
||||
return 0, nil, 0, wire.ParseError(n)
|
||||
}
|
||||
b = b[n:]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
func init() {
|
||||
if flags.ProtoLegacy {
|
||||
testValidMessages = append(testValidMessages, messageSetTestProtos...)
|
||||
testInvalidMessages = append(testInvalidMessages, messageSetInvalidTestProtos...)
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,6 +218,27 @@ var messageSetTestProtos = []testProto{
|
||||
}),
|
||||
}.Marshal(),
|
||||
},
|
||||
{
|
||||
desc: "MessageSet with unknown field",
|
||||
decodeTo: []proto.Message{func() proto.Message {
|
||||
m := &messagesetpb.MessageSetContainer{MessageSet: &messagesetpb.MessageSet{}}
|
||||
proto.SetExtension(m.MessageSet, msetextpb.E_Ext1_MessageSetExtension, &msetextpb.Ext1{
|
||||
Ext1Field1: proto.Int32(10),
|
||||
})
|
||||
return m
|
||||
}()},
|
||||
wire: pack.Message{
|
||||
pack.Tag{1, pack.BytesType}, pack.LengthPrefix(pack.Message{
|
||||
pack.Tag{1, pack.StartGroupType},
|
||||
pack.Tag{2, pack.VarintType}, pack.Varint(1000),
|
||||
pack.Tag{3, pack.BytesType}, pack.LengthPrefix(pack.Message{
|
||||
pack.Tag{1, pack.VarintType}, pack.Varint(10),
|
||||
}),
|
||||
pack.Tag{4, pack.VarintType}, pack.Varint(0),
|
||||
pack.Tag{1, pack.EndGroupType},
|
||||
}),
|
||||
}.Marshal(),
|
||||
},
|
||||
{
|
||||
desc: "MessageSet with required field set",
|
||||
checkFastInit: true,
|
||||
@ -257,3 +279,34 @@ var messageSetTestProtos = []testProto{
|
||||
}.Marshal(),
|
||||
},
|
||||
}
|
||||
|
||||
var messageSetInvalidTestProtos = []testProto{
|
||||
{
|
||||
desc: "MessageSet with type id 0",
|
||||
decodeTo: []proto.Message{
|
||||
(*messagesetpb.MessageSetContainer)(nil),
|
||||
},
|
||||
wire: pack.Message{
|
||||
pack.Tag{1, pack.BytesType}, pack.LengthPrefix(pack.Message{
|
||||
pack.Tag{1, pack.StartGroupType},
|
||||
pack.Tag{2, pack.VarintType}, pack.Uvarint(0),
|
||||
pack.Tag{3, pack.BytesType}, pack.LengthPrefix(pack.Message{}),
|
||||
pack.Tag{1, pack.EndGroupType},
|
||||
}),
|
||||
}.Marshal(),
|
||||
},
|
||||
{
|
||||
desc: "MessageSet with type id overflowing int32",
|
||||
decodeTo: []proto.Message{
|
||||
(*messagesetpb.MessageSetContainer)(nil),
|
||||
},
|
||||
wire: pack.Message{
|
||||
pack.Tag{1, pack.BytesType}, pack.LengthPrefix(pack.Message{
|
||||
pack.Tag{1, pack.StartGroupType},
|
||||
pack.Tag{2, pack.VarintType}, pack.Uvarint(0x80000000),
|
||||
pack.Tag{3, pack.BytesType}, pack.LengthPrefix(pack.Message{}),
|
||||
pack.Tag{1, pack.EndGroupType},
|
||||
}),
|
||||
}.Marshal(),
|
||||
},
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user