|
|
@@ -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
|
|
|
}
|
|
|
|
|
|
@@ -1220,6 +1231,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
|
|
|
return err
|
|
|
}
|
|
|
}
|
|
|
+ if len(o.buf) > maxMarshalSize {
|
|
|
+ return ErrTooLarge
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -1236,6 +1250,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...)
|
|
|
}
|