Skip to content

Commit

Permalink
[2.9.x] internal/miscutil: fix ReadInto returning partial reads durin…
Browse files Browse the repository at this point in the history
…g errors (#9776)

`ReadInto` is used to read streams into a buffer. This is used for
reading chunks out of object storage. Chunks have a set maximum size so
they are a natural fit for this pattern.

The bug is in the check for EOF. The `|| n2 == 0` matches cases where
there is an error and n == 0 (probably most errors)
```
errors.Is(err, io.EOF) || n2 == 0
```
  • Loading branch information
brendoncarroll committed Feb 26, 2024
1 parent 5323669 commit 01b7337
Showing 1 changed file with 6 additions and 10 deletions.
16 changes: 6 additions & 10 deletions src/internal/miscutil/miscutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,18 +104,14 @@ func CacheFunc[K comparable, V any](f func(K) V, size int) func(K) V {
// ReadInto reads into dst until the end of the stream.
// If the stream has more than len(dst) bytes, an io.ErrShortBuffer error is returned.
func ReadInto(dst []byte, r io.Reader) (int, error) {
var n int
for n < len(dst) {
n2, err := r.Read(dst[n:])
if errors.Is(err, io.EOF) || n2 == 0 {
n += n2
return n, nil
n, err := io.ReadFull(r, dst)
if err != nil {
if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
err = nil
}
if err != nil {
return 0, errors.EnsureStack(err)
}
n += n2
return n, err
}

// If we got here, it means the buffer is full.
// Now to check if there is anything more to read.
// If we get io.EOF, and nothing else, then we don't need to error.
Expand Down

0 comments on commit 01b7337

Please sign in to comment.