...
1
2
3
4
5 package zstd
6
7 import (
8 "bytes"
9 "io"
10 "os"
11 "os/exec"
12 "testing"
13 )
14
15
16 var badStrings = []string{
17 "(\xb5/\xfdd00,\x05\x00\xc4\x0400000000000000000000000000000000000000000000000000000000000000000000000000000 \xa07100000000000000000000000000000000000000000000000000000000000000000000000000aM\x8a2y0B\b",
18 "(\xb5/\xfd00$\x05\x0020 00X70000a70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
19 "(\xb5/\xfd00$\x05\x0020 00B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
20 "(\xb5/\xfd00}\x00\x0020\x00\x9000000000000",
21 "(\xb5/\xfd00}\x00\x00&0\x02\x830!000000000",
22 "(\xb5/\xfd\x1002000$\x05\x0010\xcc0\xa8100000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
23 "(\xb5/\xfd\x1002000$\x05\x0000\xcc0\xa8100d\x0000001000000000000000000000000000000000000000000000000000000000000000000000000\x000000000000000000000000000000000000000000000000000000000000000000000000000000",
24 "(\xb5/\xfd001\x00\x0000000000000000000",
25 "(\xb5/\xfd00\xec\x00\x00&@\x05\x05A7002\x02\x00\x02\x00\x02\x0000000000000000",
26 "(\xb5/\xfd00\xec\x00\x00V@\x05\x0517002\x02\x00\x02\x00\x02\x0000000000000000",
27 "\x50\x2a\x4d\x18\x02\x00\x00\x00",
28 }
29
30
31 func FuzzReader(f *testing.F) {
32 for _, test := range tests {
33 f.Add([]byte(test.compressed))
34 }
35 for _, s := range badStrings {
36 f.Add([]byte(s))
37 }
38 f.Fuzz(func(t *testing.T, b []byte) {
39 r := NewReader(bytes.NewReader(b))
40 io.Copy(io.Discard, r)
41 })
42 }
43
44
45
46
47
48 func FuzzDecompressor(f *testing.F) {
49 zstd := findZstd(f)
50
51 for _, test := range tests {
52 f.Add([]byte(test.uncompressed))
53 }
54
55
56 f.Add(bytes.Repeat([]byte("abcdefghijklmnop"), 256))
57 var buf bytes.Buffer
58 for i := 0; i < 256; i++ {
59 buf.WriteByte(byte(i))
60 }
61 f.Add(bytes.Repeat(buf.Bytes(), 64))
62 f.Add(bigData(f))
63
64 f.Fuzz(func(t *testing.T, b []byte) {
65 cmd := exec.Command(zstd, "-z")
66 cmd.Stdin = bytes.NewReader(b)
67 var compressed bytes.Buffer
68 cmd.Stdout = &compressed
69 cmd.Stderr = os.Stderr
70 if err := cmd.Run(); err != nil {
71 t.Errorf("running zstd failed: %v", err)
72 }
73
74 r := NewReader(bytes.NewReader(compressed.Bytes()))
75 got, err := io.ReadAll(r)
76 if err != nil {
77 t.Fatal(err)
78 }
79 if !bytes.Equal(got, b) {
80 showDiffs(t, got, b)
81 }
82 })
83 }
84
85
86
87 func FuzzReverse(f *testing.F) {
88 zstd := findZstd(f)
89
90 for _, test := range tests {
91 f.Add([]byte(test.compressed))
92 }
93
94
95 fuzzing = true
96 defer func() { fuzzing = false }()
97
98 f.Fuzz(func(t *testing.T, b []byte) {
99 r := NewReader(bytes.NewReader(b))
100 goExp, goErr := io.ReadAll(r)
101
102 cmd := exec.Command(zstd, "-d")
103 cmd.Stdin = bytes.NewReader(b)
104 var uncompressed bytes.Buffer
105 cmd.Stdout = &uncompressed
106 cmd.Stderr = os.Stderr
107 zstdErr := cmd.Run()
108 zstdExp := uncompressed.Bytes()
109
110 if goErr == nil && zstdErr == nil {
111 if !bytes.Equal(zstdExp, goExp) {
112 showDiffs(t, zstdExp, goExp)
113 }
114 } else {
115
116
117
118
119
120
121
122
123
124
125 c := len(goExp)
126 if c > len(zstdExp) {
127 c = len(zstdExp)
128 }
129 goExp = goExp[:c]
130 zstdExp = zstdExp[:c]
131 if !bytes.Equal(goExp, zstdExp) {
132 t.Error("byte mismatch after error")
133 t.Logf("Go error: %v\n", goErr)
134 t.Logf("zstd error: %v\n", zstdErr)
135 showDiffs(t, zstdExp, goExp)
136 }
137 }
138 })
139 }
140
View as plain text