1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
package lz4
import (
"bytes"
"fmt"
"io"
"github.com/pierrec/lz4/v4"
)
// Fuzz function for the Reader and Writer.
func Fuzz(data []byte) int {
var (
r = bytes.NewReader(data)
w = new(bytes.Buffer)
pr, pw = io.Pipe()
zr = lz4.NewReader(pr)
zw = lz4.NewWriter(pw)
)
// Compress.
go func() {
_, err := io.Copy(zw, r)
if err != nil {
panic(err)
}
err = zw.Close()
if err != nil {
panic(err)
}
err = pw.Close()
if err != nil {
panic(err)
}
}()
// Decompress.
_, err := io.Copy(w, zr)
if err != nil {
panic(err)
}
// Check that the data is valid.
if !bytes.Equal(data, w.Bytes()) {
panic("not equal")
}
return 1
}
// CompressBlock with various destination sizes.
// Shares its corpus with Fuzz.
//
// go-fuzz-build && go-fuzz -func=FuzzCompressBlock
func FuzzCompressBlock(data []byte) int {
var (
bound = lz4.CompressBlockBound(len(data))
c lz4.Compressor
comp = make([]byte, lz4.CompressBlockBound(len(data)))
keep = 0
)
for _, b := range []int{bound, len(data), len(data) - len(data)>>1} {
n, err := c.CompressBlock(data, comp[:b:b])
switch {
case err != nil && b == bound: // Should always work.
panic(err)
case n > b:
panic(fmt.Sprintf("n = %d > b = %d", n, b))
}
}
return keep
}
// Fuzzer for UncompressBlock: tries to decompress into a block the same size
// as the input.
//
// go-fuzz-build && go-fuzz -func=FuzzUncompressBlock -workdir=uncompress
func FuzzUncompressBlock(data []byte) int {
decomp := make([]byte, len(data)+16-len(data)%8)
for i := range decomp {
decomp[i] = byte(i)
}
decomp = decomp[:len(data)]
n, err := lz4.UncompressBlock(data, decomp)
if n > len(decomp) {
panic("uncompressed length greater than buffer")
}
decomp = decomp[:cap(decomp)]
for i := len(data); i < len(decomp); i++ {
if decomp[i] != byte(i) {
panic("UncompressBlock wrote out of bounds")
}
}
if err != nil {
return 0
}
return 1
}
|