aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexander Yastrebov <yastrebov.alex@gmail.com>2023-09-27 01:53:38 +0000
committerGopher Robot <gobot@golang.org>2023-09-27 14:35:13 +0000
commit4a310877f23140b45bd86a45b8c1fc7d69ba2d29 (patch)
tree92f1979d70adc41b156fd5796db45cb11a2c22ee /src
parent48042aa09c2f878c4faa576948b07fe625c4707a (diff)
downloadgo-4a310877f23140b45bd86a45b8c1fc7d69ba2d29.tar.xz
internal/zstd: configure window size for single segment frames
Set window size to frame content size when single segment flag is set. For #62513 Change-Id: I2a60c33123aca4f6a631e6d625f4582ff31a63cb GitHub-Last-Rev: 9bafe01e45aad6a9f22abca08b25b2b8d9107040 GitHub-Pull-Request: golang/go#63224 Reviewed-on: https://go-review.googlesource.com/c/go/+/531075 Auto-Submit: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Bryan Mills <bcmills@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/internal/zstd/testdata/1890a371.gettysburg.txt-100x.zstbin0 -> 826 bytes
-rw-r--r--src/internal/zstd/testdata/README10
-rw-r--r--src/internal/zstd/zstd.go22
-rw-r--r--src/internal/zstd/zstd_test.go35
4 files changed, 58 insertions, 9 deletions
diff --git a/src/internal/zstd/testdata/1890a371.gettysburg.txt-100x.zst b/src/internal/zstd/testdata/1890a371.gettysburg.txt-100x.zst
new file mode 100644
index 0000000000..afb4a2769b
--- /dev/null
+++ b/src/internal/zstd/testdata/1890a371.gettysburg.txt-100x.zst
Binary files differ
diff --git a/src/internal/zstd/testdata/README b/src/internal/zstd/testdata/README
new file mode 100644
index 0000000000..1a6dbb3a8f
--- /dev/null
+++ b/src/internal/zstd/testdata/README
@@ -0,0 +1,10 @@
+This directory holds files for testing zstd.NewReader.
+
+Each one is a Zstandard compressed file named as hash.arbitrary-name.zst,
+where hash is the first eight hexadecimal digits of the SHA256 hash
+of the expected uncompressed content:
+
+ zstd -d < 1890a371.gettysburg.txt-100x.zst | sha256sum | head -c 8
+ 1890a371
+
+The test uses hash value to verify decompression result.
diff --git a/src/internal/zstd/zstd.go b/src/internal/zstd/zstd.go
index 60551a4371..1a7a0a381b 100644
--- a/src/internal/zstd/zstd.go
+++ b/src/internal/zstd/zstd.go
@@ -235,10 +235,7 @@ retry:
// Figure out the maximum amount of data we need to retain
// for backreferences.
var windowSize int
- if singleSegment {
- // No window required, as all the data is in a single buffer.
- windowSize = 0
- } else {
+ if !singleSegment {
// Window descriptor. RFC 3.1.1.1.2.
windowDescriptor := r.scratch[0]
exponent := uint64(windowDescriptor >> 3)
@@ -252,11 +249,6 @@ retry:
if fuzzing && (windowLog > 31 || windowSize > 1<<27) {
return r.makeError(relativeOffset, "windowSize too large")
}
-
- // RFC 8878 permits us to set an 8M max on window size.
- if windowSize > 8<<20 {
- windowSize = 8 << 20
- }
}
// Frame_Content_Size. RFC 3.1.1.4.
@@ -278,6 +270,18 @@ retry:
panic("unreachable")
}
+ // RFC 3.1.1.1.2.
+ // When Single_Segment_Flag is set, Window_Descriptor is not present.
+ // In this case, Window_Size is Frame_Content_Size.
+ if singleSegment {
+ windowSize = int(r.remainingFrameSize)
+ }
+
+ // RFC 8878 3.1.1.1.1.2. permits us to set an 8M max on window size.
+ if windowSize > 8<<20 {
+ windowSize = 8 << 20
+ }
+
relativeOffset += headerSize
r.sawFrameHeader = true
diff --git a/src/internal/zstd/zstd_test.go b/src/internal/zstd/zstd_test.go
index c2914bb1f4..e5c964c307 100644
--- a/src/internal/zstd/zstd_test.go
+++ b/src/internal/zstd/zstd_test.go
@@ -6,12 +6,14 @@ package zstd
import (
"bytes"
+ "crypto/sha256"
"fmt"
"internal/race"
"internal/testenv"
"io"
"os"
"os/exec"
+ "path/filepath"
"strings"
"sync"
"testing"
@@ -237,6 +239,39 @@ func TestAlloc(t *testing.T) {
}
}
+func TestFileSamples(t *testing.T) {
+ samples, err := os.ReadDir("testdata")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ for _, sample := range samples {
+ name := sample.Name()
+ if !strings.HasSuffix(name, ".zst") {
+ continue
+ }
+
+ t.Run(name, func(t *testing.T) {
+ f, err := os.Open(filepath.Join("testdata", name))
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ r := NewReader(f)
+ h := sha256.New()
+ if _, err := io.Copy(h, r); err != nil {
+ t.Fatal(err)
+ }
+ got := fmt.Sprintf("%x", h.Sum(nil))[:8]
+
+ want, _, _ := strings.Cut(name, ".")
+ if got != want {
+ t.Errorf("Wrong uncompressed content hash: got %s, want %s", got, want)
+ }
+ })
+ }
+}
+
func BenchmarkLarge(b *testing.B) {
b.StopTimer()
b.ReportAllocs()