io: avoid integer overflow in NewSectionReader

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>
This commit is contained in:
Ian Lance Taylor 2021-09-27 14:27:59 -07:00
parent cd4d59232e
commit 12e8ffc18e
2 changed files with 24 additions and 1 deletions

View 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

View 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 {