aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/golang/protobuf/proto/encode.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/golang/protobuf/proto/encode.go')
-rw-r--r--vendor/github.com/golang/protobuf/proto/encode.go52
1 files changed, 42 insertions, 10 deletions
diff --git a/vendor/github.com/golang/protobuf/proto/encode.go b/vendor/github.com/golang/protobuf/proto/encode.go
index eb7e047..8c1b8fd 100644
--- a/vendor/github.com/golang/protobuf/proto/encode.go
+++ b/vendor/github.com/golang/protobuf/proto/encode.go
@@ -70,6 +70,10 @@ var (
// ErrNil is the error returned if Marshal is called with nil.
ErrNil = errors.New("proto: Marshal called with nil")
+
+ // ErrTooLarge is the error returned if Marshal is called with a
+ // message that encodes to >2GB.
+ ErrTooLarge = errors.New("proto: message encodes to over 2 GB")
)
// The fundamental encoders that put bytes on the wire.
@@ -78,6 +82,10 @@ var (
const maxVarintBytes = 10 // maximum length of a varint
+// maxMarshalSize is the largest allowed size of an encoded protobuf,
+// since C++ and Java use signed int32s for the size.
+const maxMarshalSize = 1<<31 - 1
+
// EncodeVarint returns the varint encoding of x.
// This is the format for the
// int32, int64, uint32, uint64, bool, and enum
@@ -277,6 +285,9 @@ func (p *Buffer) Marshal(pb Message) error {
stats.Encode++
}
+ if len(p.buf) > maxMarshalSize {
+ return ErrTooLarge
+ }
return err
}
@@ -1062,10 +1073,25 @@ func size_slice_struct_group(p *Properties, base structPointer) (n int) {
// Encode an extension map.
func (o *Buffer) enc_map(p *Properties, base structPointer) error {
- v := *structPointer_ExtMap(base, p.field)
- if err := encodeExtensionMap(v); err != nil {
+ exts := structPointer_ExtMap(base, p.field)
+ if err := encodeExtensionsMap(*exts); err != nil {
return err
}
+
+ return o.enc_map_body(*exts)
+}
+
+func (o *Buffer) enc_exts(p *Properties, base structPointer) error {
+ exts := structPointer_Extensions(base, p.field)
+ if err := encodeExtensions(exts); err != nil {
+ return err
+ }
+ v, _ := exts.extensionsRead()
+
+ return o.enc_map_body(v)
+}
+
+func (o *Buffer) enc_map_body(v map[int32]Extension) error {
// Fast-path for common cases: zero or one extensions.
if len(v) <= 1 {
for _, e := range v {
@@ -1088,8 +1114,13 @@ func (o *Buffer) enc_map(p *Properties, base structPointer) error {
}
func size_map(p *Properties, base structPointer) int {
- v := *structPointer_ExtMap(base, p.field)
- return sizeExtensionMap(v)
+ v := structPointer_ExtMap(base, p.field)
+ return extensionsMapSize(*v)
+}
+
+func size_exts(p *Properties, base structPointer) int {
+ v := structPointer_Extensions(base, p.field)
+ return extensionsSize(v)
}
// Encode a map field.
@@ -1118,7 +1149,7 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil {
return err
}
- if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil {
+ if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil && err != ErrNil {
return err
}
return nil
@@ -1128,11 +1159,6 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
for _, key := range v.MapKeys() {
val := v.MapIndex(key)
- // The only illegal map entry values are nil message pointers.
- if val.Kind() == reflect.Ptr && val.IsNil() {
- return errors.New("proto: map has nil element")
- }
-
keycopy.Set(key)
valcopy.Set(val)
@@ -1220,6 +1246,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
return err
}
}
+ if len(o.buf) > maxMarshalSize {
+ return ErrTooLarge
+ }
}
}
@@ -1236,6 +1265,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
// Add unrecognized fields at the end.
if prop.unrecField.IsValid() {
v := *structPointer_Bytes(base, prop.unrecField)
+ if len(o.buf)+len(v) > maxMarshalSize {
+ return ErrTooLarge
+ }
if len(v) > 0 {
o.buf = append(o.buf, v...)
}