]> Cypherpunks.ru repositories - gostls13.git/commitdiff
io: avoid integer overflow in NewSectionReader
authorIan Lance Taylor <iant@golang.org>
Mon, 27 Sep 2021 21:27:59 +0000 (14:27 -0700)
committerIan Lance Taylor <iant@golang.org>
Mon, 27 Sep 2021 22:57:08 +0000 (22:57 +0000)
Fixes #48620

Change-Id: I37a5909ad27dc4a170929cb2e2ed1045cf524d59
Reviewed-on: https://go-review.googlesource.com/c/go/+/352629
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>

src/io/io.go
src/io/io_test.go

index 4e49a782dce679e85dc5feff5e66731f1694e05d..cb2a37e4270944fd69b8327f584d71913f159fb5 100644 (file)
@@ -479,7 +479,16 @@ func (l *LimitedReader) Read(p []byte) (n int, err error) {
 // NewSectionReader returns a SectionReader that reads from r
 // starting at offset off and stops with EOF after n bytes.
 func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader {
-       return &SectionReader{r, off, off, off + n}
+       var remaining int64
+       const maxint64 = 1<<63 - 1
+       if off <= maxint64-n {
+               remaining = n + off
+       } else {
+               // Overflow, with no way to return error.
+               // Assume we can read up to an offset of 1<<63 - 1.
+               remaining = maxint64
+       }
+       return &SectionReader{r, off, off, remaining}
 }
 
 // SectionReader implements Read, Seek, and ReadAt on a section
index 5b355e8c55b1692eb543cdc66cbed0593bb6efd4..308846048095652c8974517dbac250a6278a2b88 100644 (file)
@@ -430,6 +430,20 @@ func TestSectionReader_Size(t *testing.T) {
        }
 }
 
+func TestSectionReader_Max(t *testing.T) {
+       r := strings.NewReader("abcdef")
+       const maxint64 = 1<<63 - 1
+       sr := NewSectionReader(r, 3, maxint64)
+       n, err := sr.Read(make([]byte, 3))
+       if n != 3 || err != nil {
+               t.Errorf("Read = %v %v, want 3, nil", n, err)
+       }
+       n, err = sr.Read(make([]byte, 3))
+       if n != 0 || err != EOF {
+               t.Errorf("Read = %v, %v, want 0, EOF", n, err)
+       }
+}
+
 // largeWriter returns an invalid count that is larger than the number
 // of bytes provided (issue 39978).
 type largeWriter struct {