Skip to content

Commit

Permalink
internal/zstd: fix copyFromWindow
Browse files Browse the repository at this point in the history
Fix copyFromWindow when match extends past initial buffer size

For golang#62513
  • Loading branch information
AlexanderYastrebov committed Sep 26, 2023
1 parent 9881d62 commit 84c0a70
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 26 deletions.
44 changes: 18 additions & 26 deletions src/internal/zstd/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,46 +391,38 @@ func (r *Reader) copyFromWindow(rbr *reverseBitReader, offset, match uint32) err
return rbr.makeError("invalid zero offset")
}

// Offset may point into the buffer or the window and
// match may extend past the end of the initial buffer.
// |--r.window--|--r.buffer--|
// |<-----offset------|
// |------match----------->|
bufferOffset := uint32(0)
lenBlock := uint32(len(r.buffer))
if lenBlock < offset {
lenWindow := r.window.len()
windowOffset := offset - lenBlock
if windowOffset > lenWindow {
copy := offset - lenBlock
if copy > lenWindow {
return rbr.makeError("offset past window")
}
from := lenWindow - windowOffset
if from+match <= lenWindow {
r.buffer = r.window.appendTo(r.buffer, from, from+match)
return nil
}
r.buffer = r.window.appendTo(r.buffer, from, lenWindow)
copied := lenWindow - from
offset -= copied
match -= copied

if offset == 0 && match > 0 {
return rbr.makeError("invalid offset")
windowOffset := lenWindow - copy
if copy > match {
copy = match
}
}

from := lenBlock - offset
if offset >= match {
r.buffer = append(r.buffer, r.buffer[from:from+match]...)
return nil
r.buffer = r.window.appendTo(r.buffer, windowOffset, windowOffset+copy)
match -= copy
} else {
bufferOffset = lenBlock - offset
}

// We are being asked to copy data that we are adding to the
// buffer in the same copy.
for match > 0 {
var copy uint32
if offset >= match {
copy := uint32(len(r.buffer)) - bufferOffset
if copy > match {
copy = match
} else {
copy = offset
}
r.buffer = append(r.buffer, r.buffer[from:from+copy]...)
r.buffer = append(r.buffer, r.buffer[bufferOffset:bufferOffset+copy]...)
match -= copy
from += copy
}
return nil
}
Binary file added src/internal/zstd/testdata/1b977e9f.x-1000000x.zst
Binary file not shown.

0 comments on commit 84c0a70

Please sign in to comment.