1
2
3
4 package flate
5
6 import (
7 "bytes"
8 "flag"
9 "io"
10 "os"
11 "strconv"
12 "testing"
13
14 "github.com/klauspost/compress/internal/fuzz"
15 )
16
17
18 var fuzzStartF = flag.Int("start", HuffmanOnly, "Start fuzzing at this level")
19 var fuzzEndF = flag.Int("end", BestCompression, "End fuzzing at this level (inclusive)")
20 var fuzzMaxF = flag.Int("max", 1<<20, "Maximum input size")
21 var fuzzSLF = flag.Bool("sl", true, "Include stateless encodes")
22 var fuzzWindow = flag.Bool("windows", true, "Include windowed encodes")
23
24 func TestMain(m *testing.M) {
25 flag.Parse()
26 os.Exit(m.Run())
27 }
28
29 func FuzzEncoding(f *testing.F) {
30 fuzz.AddFromZip(f, "testdata/regression.zip", fuzz.TypeRaw, false)
31 fuzz.AddFromZip(f, "testdata/fuzz/encode-raw-corpus.zip", fuzz.TypeRaw, testing.Short())
32 fuzz.AddFromZip(f, "testdata/fuzz/FuzzEncoding.zip", fuzz.TypeGoFuzz, testing.Short())
33
34 startFuzz := *fuzzStartF
35 endFuzz := *fuzzEndF
36 maxSize := *fuzzMaxF
37 stateless := *fuzzSLF
38 fuzzWindow := *fuzzWindow
39
40 decoder := NewReader(nil)
41 buf := new(bytes.Buffer)
42 encs := make([]*Writer, endFuzz-startFuzz+1)
43 for i := range encs {
44 var err error
45 encs[i], err = NewWriter(nil, i+startFuzz)
46 if err != nil {
47 f.Fatal(err.Error())
48 }
49 }
50
51 f.Fuzz(func(t *testing.T, data []byte) {
52 if len(data) > maxSize {
53 return
54 }
55 for level := startFuzz; level <= endFuzz; level++ {
56 msg := "level " + strconv.Itoa(level) + ":"
57 buf.Reset()
58 fw := encs[level-startFuzz]
59 fw.Reset(buf)
60 n, err := fw.Write(data)
61 if n != len(data) {
62 t.Fatal(msg + "short write")
63 }
64 if err != nil {
65 t.Fatal(msg + err.Error())
66 }
67 err = fw.Close()
68 if err != nil {
69 t.Fatal(msg + err.Error())
70 }
71 decoder.(Resetter).Reset(buf, nil)
72 data2, err := io.ReadAll(decoder)
73 if err != nil {
74 t.Fatal(msg + err.Error())
75 }
76 if !bytes.Equal(data, data2) {
77 t.Fatal(msg + "not equal")
78 }
79
80 msg = "level " + strconv.Itoa(level) + " (reset):"
81 buf.Reset()
82 fw.Reset(buf)
83 n, err = fw.Write(data)
84 if n != len(data) {
85 t.Fatal(msg + "short write")
86 }
87 if err != nil {
88 t.Fatal(msg + err.Error())
89 }
90 err = fw.Close()
91 if err != nil {
92 t.Fatal(msg + err.Error())
93 }
94 decoder.(Resetter).Reset(buf, nil)
95 data2, err = io.ReadAll(decoder)
96 if err != nil {
97 t.Fatal(msg + err.Error())
98 }
99 if !bytes.Equal(data, data2) {
100 t.Fatal(msg + "not equal")
101 }
102 }
103 if stateless {
104
105 msg := "stateless:"
106 buf.Reset()
107 err := StatelessDeflate(buf, data[:len(data)/2], false, nil)
108 if err != nil {
109 t.Error(err)
110 }
111
112
113 dict := data[:len(data)/2]
114 err = StatelessDeflate(buf, data[len(data)/2:], true, dict)
115 if err != nil {
116 t.Error(err)
117 }
118
119 decoder.(Resetter).Reset(buf, nil)
120 data2, err := io.ReadAll(decoder)
121 if err != nil {
122 t.Error(err)
123 }
124 if !bytes.Equal(data, data2) {
125
126 t.Error(msg + "not equal")
127 }
128 }
129 if fuzzWindow {
130 msg := "windowed:"
131 buf.Reset()
132 fw, err := NewWriterWindow(buf, 1000)
133 if err != nil {
134 t.Fatal(msg + err.Error())
135 }
136 fw.Reset(buf)
137 n, err := fw.Write(data)
138 if n != len(data) {
139 t.Fatal(msg + "short write")
140 }
141 if err != nil {
142 t.Fatal(msg + err.Error())
143 }
144 err = fw.Close()
145 if err != nil {
146 t.Fatal(msg + err.Error())
147 }
148 decoder.(Resetter).Reset(buf, nil)
149 data2, err := io.ReadAll(decoder)
150 if err != nil {
151 t.Fatal(msg + err.Error())
152 }
153 if !bytes.Equal(data, data2) {
154 t.Fatal(msg + "not equal")
155 }
156
157 msg = msg + " (reset):"
158 buf.Reset()
159 fw.Reset(buf)
160 n, err = fw.Write(data)
161 if n != len(data) {
162 t.Fatal(msg + "short write")
163 }
164 if err != nil {
165 t.Fatal(msg + err.Error())
166 }
167 err = fw.Close()
168 if err != nil {
169 t.Fatal(msg + err.Error())
170 }
171 decoder.(Resetter).Reset(buf, nil)
172 data2, err = io.ReadAll(decoder)
173 if err != nil {
174 t.Fatal(msg + err.Error())
175 }
176 }
177 })
178 }
179
View as plain text