github.com/m10x/go/src@v0.0.0-20220112094212-ba61592315da/archive/tar/fuzz_test.go (about) 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 //go:build !android 6 // +build !android 7 8 package tar 9 10 import ( 11 "bytes" 12 "internal/testenv" 13 "io" 14 "os" 15 "path/filepath" 16 "strings" 17 "testing" 18 ) 19 20 var constrainedBuilders = map[string]bool{ 21 "windows-386-2012": true, 22 "windows-386-2008": true, 23 "js-wasm": true, 24 "android-amd64-emu": true, 25 } 26 27 func FuzzReader(f *testing.F) { 28 if constrainedBuilders[testenv.Builder()] { 29 f.Skip("builder is memory constrained") 30 } 31 testdata, err := os.ReadDir("testdata") 32 if err != nil { 33 f.Fatalf("failed to read testdata directory: %s", err) 34 } 35 for _, de := range testdata { 36 if de.IsDir() { 37 continue 38 } 39 if strings.Contains(de.Name(), "big") { 40 // skip large archives so we don't kill builders with restricted 41 // memory 42 continue 43 } 44 b, err := os.ReadFile(filepath.Join("testdata", de.Name())) 45 if err != nil { 46 f.Fatalf("failed to read testdata: %s", err) 47 } 48 f.Add(b) 49 } 50 51 f.Fuzz(func(t *testing.T, b []byte) { 52 r := NewReader(bytes.NewReader(b)) 53 type file struct { 54 header *Header 55 content []byte 56 } 57 files := []file{} 58 for { 59 hdr, err := r.Next() 60 if err == io.EOF { 61 break 62 } 63 if err != nil { 64 return 65 } 66 buf := bytes.NewBuffer(nil) 67 if _, err := io.Copy(buf, r); err != nil { 68 continue 69 } 70 files = append(files, file{header: hdr, content: buf.Bytes()}) 71 } 72 73 // If we were unable to read anything out of the archive don't 74 // bother trying to roundtrip it. 75 if len(files) == 0 { 76 return 77 } 78 79 out := bytes.NewBuffer(nil) 80 w := NewWriter(out) 81 for _, f := range files { 82 if err := w.WriteHeader(f.header); err != nil { 83 t.Fatalf("unable to write previously parsed header: %s", err) 84 } 85 if _, err := w.Write(f.content); err != nil { 86 t.Fatalf("unable to write previously parsed content: %s", err) 87 } 88 } 89 if err := w.Close(); err != nil { 90 t.Fatalf("Unable to write archive: %s", err) 91 } 92 93 // TODO: We may want to check if the archive roundtrips. This would require 94 // taking into account addition of the two zero trailer blocks that Writer.Close 95 // appends. 96 }) 97 }