// Copyright 2026 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package flate import ( "bytes" "flag" "io" "strconv" "testing" ) // Fuzzing tweaks: var fuzzStartF = flag.Int("start", HuffmanOnly, "Start fuzzing at this level") var fuzzEndF = flag.Int("end", BestCompression, "End fuzzing at this level (inclusive)") var fuzzMaxF = flag.Int("max", 1<<20, "Maximum input size") // FuzzEncoding tests the fuzzer by doing roundtrips. // Every input is run through the fuzzer at every level. // Note: When running the fuzzer, it may hit the 10-second timeout on slower CPUs. func FuzzEncoding(f *testing.F) { startFuzz := *fuzzStartF endFuzz := *fuzzEndF maxSize := *fuzzMaxF decoder := NewReader(nil) buf, buf2 := new(bytes.Buffer), new(bytes.Buffer) encs := make([]*Writer, endFuzz-startFuzz+1) for i := range encs { var err error encs[i], err = NewWriter(nil, i+startFuzz) if err != nil { f.Fatal(err.Error()) } } f.Fuzz(func(t *testing.T, data []byte) { if len(data) > maxSize { return } for level := startFuzz; level <= endFuzz; level++ { if level == DefaultCompression { continue // Already covered. } msg := "level " + strconv.Itoa(level) + ":" buf.Reset() fw := encs[level-startFuzz] fw.Reset(buf) n, err := fw.Write(data) if n != len(data) { t.Fatal(msg, "short write") } if err != nil { t.Fatal(msg, err.Error()) } err = fw.Close() if err != nil { t.Fatal(msg, err.Error()) } compressed := buf.Bytes() err = decoder.(Resetter).Reset(buf, nil) if err != nil { t.Fatal(msg, err.Error()) } data2, err := io.ReadAll(decoder) if err != nil { t.Fatal(msg, err.Error()) } if !bytes.Equal(data, data2) { t.Fatal(msg + "decompressed not equal") } // Do it again... msg = "level " + strconv.Itoa(level) + " (reset):" buf2.Reset() fw.Reset(buf2) n, err = fw.Write(data) if n != len(data) { t.Fatal(msg + "short write") } if err != nil { t.Fatal(msg, err.Error()) } err = fw.Close() if err != nil { t.Fatal(msg, err.Error()) } compressed2 := buf2.Bytes() err = decoder.(Resetter).Reset(buf2, nil) if err != nil { t.Fatal(msg, err.Error()) } data2, err = io.ReadAll(decoder) if err != nil { t.Fatal(msg, err.Error()) } if !bytes.Equal(data, data2) { t.Fatal(msg, "decompressed not equal") } // Determinism checks will usually not be reproducible, // since it often relies on the internal state of the compressor. if !bytes.Equal(compressed, compressed2) { t.Fatal(msg, "non-deterministic output") } } }) }