proto: validate UTF-8 in proto3 strings
Change-Id: I6a495730c3f438e7b2c4ca86edade7d6f25aa47d
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/171700
Reviewed-by: Herbie Ong <herbie@google.com>
diff --git a/proto/decode.go b/proto/decode.go
index 3e00074..0b1aa3f 100644
--- a/proto/decode.go
+++ b/proto/decode.go
@@ -86,7 +86,7 @@
case fieldType.Cardinality() != protoreflect.Repeated:
valLen, err = o.unmarshalScalarField(b[tagLen:], wtyp, num, knownFields, fieldType)
case !fieldType.IsMap():
- valLen, err = o.unmarshalList(b[tagLen:], wtyp, num, knownFields.Get(num).List(), fieldType.Kind())
+ valLen, err = o.unmarshalList(b[tagLen:], wtyp, num, knownFields.Get(num).List(), fieldType)
default:
valLen, err = o.unmarshalMap(b[tagLen:], wtyp, num, knownFields.Get(num).Map(), fieldType)
}
@@ -105,8 +105,9 @@
}
func (o UnmarshalOptions) unmarshalScalarField(b []byte, wtyp wire.Type, num wire.Number, knownFields protoreflect.KnownFields, field protoreflect.FieldDescriptor) (n int, err error) {
- v, n, err := o.unmarshalScalar(b, wtyp, num, field.Kind())
- if err != nil {
+ var nerr errors.NonFatal
+ v, n, err := o.unmarshalScalar(b, wtyp, num, field)
+ if !nerr.Merge(err) {
return 0, err
}
switch field.Kind() {
@@ -124,12 +125,14 @@
knownFields.Set(num, protoreflect.ValueOf(m))
}
// Pass up errors (fatal and otherwise).
- err = o.unmarshalMessage(v.Bytes(), m)
+ if err := o.unmarshalMessage(v.Bytes(), m); !nerr.Merge(err) {
+ return n, err
+ }
default:
// Non-message scalars replace the previous value.
knownFields.Set(num, v)
}
- return n, err
+ return n, nerr.E
}
func (o UnmarshalOptions) unmarshalMap(b []byte, wtyp wire.Type, num wire.Number, mapv protoreflect.Map, field protoreflect.FieldDescriptor) (n int, err error) {
@@ -164,17 +167,19 @@
err = errUnknown
switch num {
case 1:
- key, n, err = o.unmarshalScalar(b, wtyp, num, keyField.Kind())
- if err != nil {
+ key, n, err = o.unmarshalScalar(b, wtyp, num, keyField)
+ if !nerr.Merge(err) {
break
}
+ err = nil
haveKey = true
case 2:
var v protoreflect.Value
- v, n, err = o.unmarshalScalar(b, wtyp, num, valField.Kind())
- if err != nil {
+ v, n, err = o.unmarshalScalar(b, wtyp, num, valField)
+ if !nerr.Merge(err) {
break
}
+ err = nil
switch valField.Kind() {
case protoreflect.GroupKind, protoreflect.MessageKind:
if err := o.unmarshalMessage(v.Bytes(), val.Message()); !nerr.Merge(err) {
@@ -190,7 +195,7 @@
if n < 0 {
return 0, wire.ParseError(n)
}
- } else if !nerr.Merge(err) {
+ } else if err != nil {
return 0, err
}
b = b[n:]