aboutsummaryrefslogtreecommitdiff
path: root/src/internal/zstd/zstd.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal/zstd/zstd.go')
-rw-r--r--src/internal/zstd/zstd.go28
1 files changed, 25 insertions, 3 deletions
diff --git a/src/internal/zstd/zstd.go b/src/internal/zstd/zstd.go
index 9cf62a6bac..0230076f50 100644
--- a/src/internal/zstd/zstd.go
+++ b/src/internal/zstd/zstd.go
@@ -326,12 +326,34 @@ func (r *Reader) skipFrame() error {
relativeOffset += 4
size := binary.LittleEndian.Uint32(r.scratch[:4])
+ if size == 0 {
+ r.blockOffset += int64(relativeOffset)
+ return nil
+ }
if seeker, ok := r.r.(io.Seeker); ok {
- if _, err := seeker.Seek(int64(size), io.SeekCurrent); err != nil {
- return err
+ r.blockOffset += int64(relativeOffset)
+ // Implementations of Seeker do not always detect invalid offsets,
+ // so check that the new offset is valid by comparing to the end.
+ prev, err := seeker.Seek(0, io.SeekCurrent)
+ if err != nil {
+ return r.wrapError(0, err)
+ }
+ end, err := seeker.Seek(0, io.SeekEnd)
+ if err != nil {
+ return r.wrapError(0, err)
+ }
+ if prev > end-int64(size) {
+ r.blockOffset += end - prev
+ return r.makeEOFError(0)
+ }
+
+ // The new offset is valid, so seek to it.
+ _, err = seeker.Seek(prev+int64(size), io.SeekStart)
+ if err != nil {
+ return r.wrapError(0, err)
}
- r.blockOffset += int64(relativeOffset) + int64(size)
+ r.blockOffset += int64(size)
return nil
}