...

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

Documentation: github.com/klauspost/compress/zip

     1  // Copyright 2021 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package zip
     6  
     7  import (
     8  	"bytes"
     9  	"io"
    10  	"os"
    11  	"path/filepath"
    12  	"strings"
    13  	"testing"
    14  
    15  	"github.com/klauspost/compress/internal/fuzz"
    16  )
    17  
    18  func FuzzReader(f *testing.F) {
    19  	testdata, err := os.ReadDir("testdata")
    20  	if err != nil {
    21  		f.Fatalf("failed to read testdata directory: %s", err)
    22  	}
    23  	for _, de := range testdata {
    24  		if de.IsDir() {
    25  			continue
    26  		}
    27  		b, err := os.ReadFile(filepath.Join("testdata", de.Name()))
    28  		if err != nil {
    29  			f.Fatalf("failed to read testdata: %s", err)
    30  		}
    31  		f.Add(b)
    32  	}
    33  	fuzz.AddFromZip(f, "testdata/FuzzReader-raw.zip", fuzz.TypeRaw, testing.Short())
    34  	fuzz.AddFromZip(f, "testdata/FuzzReader-enc.zip", fuzz.TypeGoFuzz, testing.Short())
    35  
    36  	f.Fuzz(func(t *testing.T, b []byte) {
    37  		r, err := NewReader(bytes.NewReader(b), int64(len(b)))
    38  		if err != nil {
    39  			return
    40  		}
    41  
    42  		type file struct {
    43  			header  *FileHeader
    44  			content []byte
    45  		}
    46  		files := make([]file, 0, len(r.File))
    47  
    48  		for i, f := range r.File {
    49  			fr, err := f.Open()
    50  			if err != nil {
    51  				continue
    52  			}
    53  			// No more than 1MiB per file
    54  			limit := int64(1 << 20)
    55  			if i < 100 {
    56  				limit = 10
    57  			}
    58  			content, err := io.ReadAll(io.LimitReader(fr, limit))
    59  			if err != nil {
    60  				continue
    61  			}
    62  
    63  			files = append(files, file{header: &f.FileHeader, content: content})
    64  			if _, err := r.Open(f.Name); err != nil {
    65  				continue
    66  			}
    67  		}
    68  
    69  		// If we were unable to read anything out of the archive don't
    70  		// bother trying to roundtrip it.
    71  		if len(files) == 0 {
    72  			return
    73  		}
    74  
    75  		w := NewWriter(io.Discard)
    76  		for _, f := range files {
    77  			ww, err := w.CreateHeader(f.header)
    78  			if err != nil {
    79  				t.Fatalf("unable to write previously parsed header: %s", err)
    80  			}
    81  			if !strings.HasSuffix(f.header.Name, "/") {
    82  				if _, err := ww.Write(f.content); err != nil {
    83  					t.Fatalf("unable to write previously parsed content: %s", err)
    84  				}
    85  			}
    86  		}
    87  
    88  		if err := w.Close(); err != nil {
    89  			t.Fatalf("Unable to write archive: %s", err)
    90  		}
    91  
    92  		// TODO: We may want to check if the archive roundtrips.
    93  	})
    94  }
    95  

View as plain text