aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/golang/protobuf/proto/table_unmarshal.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/golang/protobuf/proto/table_unmarshal.go')
-rw-r--r--vendor/github.com/golang/protobuf/proto/table_unmarshal.go49
1 files changed, 25 insertions, 24 deletions
diff --git a/vendor/github.com/golang/protobuf/proto/table_unmarshal.go b/vendor/github.com/golang/protobuf/proto/table_unmarshal.go
index 90ec6c2..de868ae 100644
--- a/vendor/github.com/golang/protobuf/proto/table_unmarshal.go
+++ b/vendor/github.com/golang/protobuf/proto/table_unmarshal.go
@@ -138,8 +138,8 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
if u.isMessageSet {
return UnmarshalMessageSet(b, m.offset(u.extensions).toExtensions())
}
- var reqMask uint64 // bitmask of required fields we've seen.
- var rnse *RequiredNotSetError // an instance of a RequiredNotSetError returned by a submessage.
+ var reqMask uint64 // bitmask of required fields we've seen.
+ var errLater error
for len(b) > 0 {
// Read tag and wire type.
// Special case 1 and 2 byte varints.
@@ -175,17 +175,20 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
reqMask |= f.reqMask
continue
}
- if r, ok := err.(*RequiredNotSetError); ok {
+ if r, ok := err.(*RequiredNotSetError); ok && errLater == nil {
// Remember this error, but keep parsing. We need to produce
// a full parse even if a required field is missing.
- rnse = r
+ errLater = r
reqMask |= f.reqMask
continue
}
if err != errInternalBadWireType {
if err == errInvalidUTF8 {
- fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
- err = fmt.Errorf("proto: string field %q contains invalid UTF-8", fullName)
+ if errLater == nil {
+ fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
+ errLater = &invalidUTF8Error{fullName}
+ }
+ continue
}
return err
}
@@ -245,20 +248,16 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
emap[int32(tag)] = e
}
}
- if rnse != nil {
- // A required field of a submessage/group is missing. Return that error.
- return rnse
- }
- if reqMask != u.reqMask {
+ if reqMask != u.reqMask && errLater == nil {
// A required field of this message is missing.
for _, n := range u.reqFields {
if reqMask&1 == 0 {
- return &RequiredNotSetError{n}
+ errLater = &RequiredNotSetError{n}
}
reqMask >>= 1
}
}
- return nil
+ return errLater
}
// computeUnmarshalInfo fills in u with information for use
@@ -1529,10 +1528,10 @@ func unmarshalUTF8StringValue(b []byte, f pointer, w int) ([]byte, error) {
return nil, io.ErrUnexpectedEOF
}
v := string(b[:x])
+ *f.toString() = v
if !utf8.ValidString(v) {
- return nil, errInvalidUTF8
+ return b[x:], errInvalidUTF8
}
- *f.toString() = v
return b[x:], nil
}
@@ -1549,10 +1548,10 @@ func unmarshalUTF8StringPtr(b []byte, f pointer, w int) ([]byte, error) {
return nil, io.ErrUnexpectedEOF
}
v := string(b[:x])
+ *f.toStringPtr() = &v
if !utf8.ValidString(v) {
- return nil, errInvalidUTF8
+ return b[x:], errInvalidUTF8
}
- *f.toStringPtr() = &v
return b[x:], nil
}
@@ -1569,11 +1568,11 @@ func unmarshalUTF8StringSlice(b []byte, f pointer, w int) ([]byte, error) {
return nil, io.ErrUnexpectedEOF
}
v := string(b[:x])
- if !utf8.ValidString(v) {
- return nil, errInvalidUTF8
- }
s := f.toStringSlice()
*s = append(*s, v)
+ if !utf8.ValidString(v) {
+ return b[x:], errInvalidUTF8
+ }
return b[x:], nil
}
@@ -1755,6 +1754,7 @@ func makeUnmarshalMap(f *reflect.StructField) unmarshaler {
// Maps will be somewhat slow. Oh well.
// Read key and value from data.
+ var nerr nonFatal
k := reflect.New(kt)
v := reflect.New(vt)
for len(b) > 0 {
@@ -1775,7 +1775,7 @@ func makeUnmarshalMap(f *reflect.StructField) unmarshaler {
err = errInternalBadWireType // skip unknown tag
}
- if err == nil {
+ if nerr.Merge(err) {
continue
}
if err != errInternalBadWireType {
@@ -1798,7 +1798,7 @@ func makeUnmarshalMap(f *reflect.StructField) unmarshaler {
// Insert into map.
m.SetMapIndex(k.Elem(), v.Elem())
- return r, nil
+ return r, nerr.E
}
}
@@ -1824,15 +1824,16 @@ func makeUnmarshalOneof(typ, ityp reflect.Type, unmarshal unmarshaler) unmarshal
// Unmarshal data into holder.
// We unmarshal into the first field of the holder object.
var err error
+ var nerr nonFatal
b, err = unmarshal(b, valToPointer(v).offset(field0), w)
- if err != nil {
+ if !nerr.Merge(err) {
return nil, err
}
// Write pointer to holder into target field.
f.asPointerTo(ityp).Elem().Set(v)
- return b, nil
+ return b, nerr.E
}
}