]> Cypherpunks repositories - gostls13.git/commitdiff
internal/zstd: handle match extending past window
authorAlexander Yastrebov <yastrebov.alex@gmail.com>
Wed, 27 Sep 2023 15:25:40 +0000 (15:25 +0000)
committerGopher Robot <gobot@golang.org>
Thu, 28 Sep 2023 17:57:43 +0000 (17:57 +0000)
For #62513

Change-Id: I59c24b254d5073140811b41497eabb91fb0046e9
GitHub-Last-Rev: 4dd16fcfa813da2b612d5753e11c163476d44b53
GitHub-Pull-Request: golang/go#63248
Reviewed-on: https://go-review.googlesource.com/c/go/+/531255
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
src/internal/zstd/block.go
src/internal/zstd/testdata/f2a8e35c.helloworld-11000x.zst [new file with mode: 0644]

index 8732661fa1d9a310000292ccec73129120796aca..11a99cd778e834c5d8afe9c34cfc46c8667546ff 100644 (file)
@@ -388,46 +388,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
 }
diff --git a/src/internal/zstd/testdata/f2a8e35c.helloworld-11000x.zst b/src/internal/zstd/testdata/f2a8e35c.helloworld-11000x.zst
new file mode 100644 (file)
index 0000000..87a8aca
Binary files /dev/null and b/src/internal/zstd/testdata/f2a8e35c.helloworld-11000x.zst differ