Skip to content

Commit e9def1a

Browse files
committed
encoding/protodelim: error out when size exceeds math.MaxInt
This results in an error (instead of a runtime panic) when users explicitly specify MaxSize=-1 and then process a too-large message. Fixes golang/protobuf#1706 For protocolbuffers/protobuf#25069 Change-Id: I8faee6a177bb8614b6ea7eff25b8cab770a7d9c7 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/734760 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Lasse Folger <lassefolger@google.com>
1 parent cb6ac5a commit e9def1a

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

encoding/protodelim/protodelim.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"encoding/binary"
1111
"fmt"
1212
"io"
13+
"math"
1314

1415
"google.golang.org/protobuf/encoding/protowire"
1516
"google.golang.org/protobuf/internal/errors"
@@ -117,7 +118,13 @@ func (o UnmarshalOptions) UnmarshalFrom(r Reader, m proto.Message) error {
117118
if maxSize == 0 {
118119
maxSize = defaultMaxSize
119120
}
120-
if maxSize != -1 && size > uint64(maxSize) {
121+
if maxSize == -1 {
122+
// No limit specified: Just check that size fits into an integer,
123+
// otherwise the make([]byte, size) call below will panic.
124+
if size > math.MaxInt {
125+
return errors.Wrap(&SizeTooLargeError{Size: size, MaxSize: math.MaxInt}, "")
126+
}
127+
} else if size > uint64(maxSize) {
121128
return errors.Wrap(&SizeTooLargeError{Size: size, MaxSize: uint64(maxSize)}, "")
122129
}
123130

encoding/protodelim/protodelim_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"encoding/binary"
1111
"errors"
1212
"io"
13+
"math"
1314
"testing"
1415

1516
"github.com/google/go-cmp/cmp"
@@ -159,6 +160,26 @@ func TestMaxSize(t *testing.T) {
159160
}
160161
}
161162

163+
func TestMaxSizeOverflow(t *testing.T) {
164+
buf := &bytes.Buffer{}
165+
sb := protowire.AppendVarint(nil, math.MaxInt+1)
166+
if _, err := buf.Write(sb); err != nil {
167+
t.Fatalf("buf.Write(%v) = _, %v", sb, err)
168+
}
169+
170+
out := &test3.TestAllTypes{}
171+
err := protodelim.UnmarshalOptions{MaxSize: -1}.UnmarshalFrom(bufio.NewReader(buf), out)
172+
173+
var errSize *protodelim.SizeTooLargeError
174+
if !errors.As(err, &errSize) {
175+
t.Errorf("protodelim.UnmarshalOptions{MaxSize: 1}.UnmarshalFrom(_, _) = %v (%T), want %T", err, err, errSize)
176+
}
177+
got, want := errSize, &protodelim.SizeTooLargeError{Size: math.MaxInt + 1, MaxSize: math.MaxInt}
178+
if diff := cmp.Diff(want, got); diff != "" {
179+
t.Errorf("protodelim.UnmarshalOptions{MaxSize: 1}.UnmarshalFrom(_, _): diff -want +got = %s", diff)
180+
}
181+
}
182+
162183
func TestUnmarshalFrom_UnexpectedEOF(t *testing.T) {
163184
buf := &bytes.Buffer{}
164185

0 commit comments

Comments
 (0)