Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fuzzing Coverage Expansion #866

Merged
merged 15 commits into from Oct 4, 2023
43 changes: 43 additions & 0 deletions fse/fse_fuzz_test.go
@@ -0,0 +1,43 @@
package fse
viktoriia-lsg marked this conversation as resolved.
Show resolved Hide resolved

import (
"bytes"
"fmt"
"testing"
"github.com/klauspost/compress/internal/fuzz"
)

func FuzzCompress(f *testing.F) {
fuzz.AddFromZip(f, "testdata/fse_compress.zip", fuzz.TypeRaw, false)
f.Fuzz(func(t *testing.T, buf0 []byte) {
var s, s2 Scratch
b, err := Compress(buf0, &s)
if err != nil || b == nil {
return
}
err = s.validateNorm()
if err != nil {
return
}
klauspost marked this conversation as resolved.
Show resolved Hide resolved
//Decompress
got, err := Decompress(b, &s2)
if err != nil || len(got) == 0 {
return
}
if !bytes.Equal(buf0, got) {
t.Fatal(fmt.Sprintln("FuzzCompress output mismatch\n", len(got), "org: \n", len(buf0)))
}
})
}

func FuzzDecompress(f *testing.F) {
fuzz.AddFromZip(f, "testdata/fse_decompress.zip", fuzz.TypeRaw, false)
f.Fuzz(func(t *testing.T, buf0 []byte) {
var s2 Scratch
//Decompress
got, err := Decompress(buf0, &s2)
if err != nil || len(got) == 0 {
return
}
})
}
Binary file added fse/testdata/fse_compress.zip
Binary file not shown.
Binary file added fse/testdata/fse_decompress.zip
Binary file not shown.
89 changes: 89 additions & 0 deletions huff0/huff0_fuzz_test.go
@@ -0,0 +1,89 @@
package huff0
viktoriia-lsg marked this conversation as resolved.
Show resolved Hide resolved

import (
"bytes"
"fmt"
"testing"
"github.com/klauspost/compress/internal/fuzz"
)

func FuzzCompress(f *testing.F) {
fuzz.AddFromZip(f, "testdata/fse_compress.zip", fuzz.TypeRaw, false)
f.Fuzz(func(t *testing.T, buf0 []byte) {
//use of Compress1X
var s Scratch
if len(buf0) > BlockSizeMax {
buf0 = buf0[:BlockSizeMax]
}
EstimateSizes(buf0, &s)
b, re, err := Compress1X(buf0, &s)
s.validateTable(s.cTable)
s.canUseTable(s.cTable)
if err != nil || b == nil {
return
}

min := s.minSize(len(buf0))

if len(s.OutData) < min {
t.Errorf("FuzzCompress: output data length (%d) below shannon limit (%d)", len(s.OutData), min)
}
if len(s.OutTable) == 0 {
t.Error("FuzzCompress: got no table definition")
}
if re {
t.Error("FuzzCompress: claimed to have re-used.")
}
if len(s.OutData) == 0 {
t.Error("FuzzCompress: got no data output")
}

dec, remain, err := ReadTable(b, nil)

//use of Decompress1X
out, err := dec.Decompress1X(remain)
if err != nil || len(out) == 0 {
return
}
if !bytes.Equal(out, buf0) {
t.Fatal(fmt.Sprintln("FuzzCompressX1 output mismatch\n", len(out), "org: \n", len(buf0)))
}

//use of Compress4X
s.Reuse = ReusePolicyAllow
b, reUsed, err := Compress4X(buf0, &s)
if err != nil || b == nil {
return
}
remain = b
if !reUsed {
dec, remain, err = ReadTable(b, dec)
if err != nil {
return
}
}
//use of Decompress4X
out, err = dec.Decompress4X(remain, len(buf0))
if err != nil || out == nil {
return
}
if !bytes.Equal(out, buf0) {
t.Fatal(fmt.Sprintln("FuzzCompressX4 output mismatch: ", len(out), ", org: ", len(buf0)))
}
})
}

func FuzzDecompress1x(f *testing.F) {
fuzz.AddFromZip(f, "testdata/huff0_decompress1x.zip", fuzz.TypeRaw, false)
f.Fuzz(func(t *testing.T, buf0 []byte) {
var s Scratch
_, remain, err := ReadTable(buf0, &s)
if err != nil {
return
}
out, err := s.Decompress1X(remain)
if err != nil || out == nil {
return
}
})
}
viktoriia-lsg marked this conversation as resolved.
Show resolved Hide resolved
Binary file added huff0/testdata/fse_compress.zip
Binary file not shown.
Binary file added huff0/testdata/huff0_decompress1x.zip
Binary file not shown.
34 changes: 34 additions & 0 deletions s2/s2_fuzz_test.go
@@ -0,0 +1,34 @@
package s2
klauspost marked this conversation as resolved.
Show resolved Hide resolved

import (
"github.com/klauspost/compress/internal/fuzz"
"testing"
)

func FuzzS2(f *testing.F) {
fuzz.AddFromZip(f, "testdata/fuzz/block-corpus-raw.zip", fuzz.TypeRaw, false)
f.Fuzz(func(t *testing.T, data []byte) {
concat, err := ConcatBlocks(nil, data, []byte{0})
if err != nil || concat == nil {
return
}

if len(data) < 9 { //to avoid errors when converting to uint64
viktoriia-lsg marked this conversation as resolved.
Show resolved Hide resolved
return
}
EstimateBlockSize(data)
encoded := make([]byte, MaxEncodedLen(len(data)))
if len(encoded) < MaxEncodedLen(len(data)) || minNonLiteralBlockSize > len(data) || len(data) > maxBlockSize {
return
}

encodeBlockGo(encoded, data)
encodeBlockBetterGo(encoded, data)
encodeBlockSnappyGo(encoded, data)
encodeBlockBetterSnappyGo(encoded, data)
dst := encodeGo(encoded, data)
if dst == nil {
return
}
klauspost marked this conversation as resolved.
Show resolved Hide resolved
})
}
Binary file added snappy/xerial/testdata/FuzzDecode_raw.zip
Binary file not shown.
44 changes: 44 additions & 0 deletions snappy/xerial/xerial_encode_fuzz_test.go
@@ -0,0 +1,44 @@
package xerial
viktoriia-lsg marked this conversation as resolved.
Show resolved Hide resolved

import (
"bytes"
"testing"
"github.com/klauspost/compress/internal/fuzz"
"github.com/klauspost/compress/s2"
)

func FuzzEncoder(f *testing.F) {
fuzz.AddFromZip(f, "testdata/fuzz/block-corpus-raw.zip", fuzz.TypeRaw, false)

f.Fuzz(func(t *testing.T, data []byte) {
encoded := Encode(make([]byte, 0, len(data)/2), data)
decoded, err := Decode(encoded)
if err != nil {
t.Errorf("input: %+v, encoded: %+v", data, encoded)
t.Fatal(err)
}
if !bytes.Equal(decoded, data) {
t.Fatal("mismatch")
}

encoded = EncodeBetter(make([]byte, 0, len(data)/2), data)
decoded, err = Decode(encoded)
if err != nil {
t.Errorf("input: %+v, encoded: %+v", data, encoded)
t.Fatal(err)
}
if !bytes.Equal(decoded, data) {
t.Fatal("mismatch")
}

encoded = s2.EncodeSnappy(make([]byte, 0, len(data)/2), data)
decoded, err = Decode(encoded)
if err != nil {
t.Errorf("input: %+v, encoded: %+v", data, encoded)
t.Fatal(err)
}
if !bytes.Equal(decoded, data) {
t.Fatal("mismatch")
}
})
}