Source file src/archive/zip/fuzz_test.go

     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  	"testing"
    13  )
    14  
    15  func FuzzReader(f *testing.F) {
    16  	testdata, err := os.ReadDir("testdata")
    17  	if err != nil {
    18  		f.Fatalf("failed to read testdata directory: %s", err)
    19  	}
    20  	for _, de := range testdata {
    21  		if de.IsDir() {
    22  			continue
    23  		}
    24  		b, err := os.ReadFile(filepath.Join("testdata", de.Name()))
    25  		if err != nil {
    26  			f.Fatalf("failed to read testdata: %s", err)
    27  		}
    28  		f.Add(b)
    29  	}
    30  
    31  	f.Fuzz(func(t *testing.T, b []byte) {
    32  		r, err := NewReader(bytes.NewReader(b), int64(len(b)))
    33  		if err != nil {
    34  			return
    35  		}
    36  
    37  		type file struct {
    38  			header  *FileHeader
    39  			content []byte
    40  		}
    41  		files := []file{}
    42  
    43  		for _, f := range r.File {
    44  			fr, err := f.Open()
    45  			if err != nil {
    46  				continue
    47  			}
    48  			content, err := io.ReadAll(fr)
    49  			if err != nil {
    50  				continue
    51  			}
    52  			files = append(files, file{header: &f.FileHeader, content: content})
    53  			if _, err := r.Open(f.Name); err != nil {
    54  				continue
    55  			}
    56  		}
    57  
    58  		// If we were unable to read anything out of the archive don't
    59  		// bother trying to roundtrip it.
    60  		if len(files) == 0 {
    61  			return
    62  		}
    63  
    64  		w := NewWriter(io.Discard)
    65  		for _, f := range files {
    66  			ww, err := w.CreateHeader(f.header)
    67  			if err != nil {
    68  				t.Fatalf("unable to write previously parsed header: %s", err)
    69  			}
    70  			if _, err := ww.Write(f.content); err != nil {
    71  				t.Fatalf("unable to write previously parsed content: %s", err)
    72  			}
    73  		}
    74  
    75  		if err := w.Close(); err != nil {
    76  			t.Fatalf("Unable to write archive: %s", err)
    77  		}
    78  
    79  		// TODO: We may want to check if the archive roundtrips.
    80  	})
    81  }
    82  

View as plain text