...

Source file src/github.com/klauspost/compress/flate/fuzz_test.go

Documentation: github.com/klauspost/compress/flate

     1  //go:build go1.18
     2  // +build go1.18
     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  // Fuzzing tweaks:
    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  			// Do it again...
    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  			// Split into two and use history...
   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  			// Use top half as dictionary...
   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  				//fmt.Printf("want:%x\ngot: %x\n", data1, data2)
   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  			// Do it again...
   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