github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/pkg/scanners/helm/parser/parser_tar.go (about) 1 package parser 2 3 import ( 4 "archive/tar" 5 "bytes" 6 "compress/gzip" 7 "errors" 8 "fmt" 9 "io" 10 "io/fs" 11 "os" 12 "path/filepath" 13 14 "github.com/liamg/memoryfs" 15 16 "github.com/khulnasoft-lab/defsec/pkg/detection" 17 ) 18 19 func (p *Parser) addTarToFS(path string) (fs.FS, error) { 20 21 var tr *tar.Reader 22 var err error 23 24 tarFS := memoryfs.CloneFS(p.workingFS) 25 if err != nil { 26 return nil, err 27 } 28 29 file, err := tarFS.Open(path) 30 if err != nil { 31 return nil, err 32 } 33 defer func() { _ = file.Close() }() 34 if detection.IsZip(path) { 35 zipped, err := gzip.NewReader(file) 36 if err != nil { 37 return nil, err 38 } 39 defer func() { _ = zipped.Close() }() 40 tr = tar.NewReader(zipped) 41 } else { 42 tr = tar.NewReader(file) 43 } 44 45 for { 46 header, err := tr.Next() 47 if err != nil { 48 if errors.Is(err, io.EOF) { 49 break 50 } 51 return nil, err 52 } 53 54 // get the individual path and extract to the current directory 55 entryPath := header.Name 56 57 switch header.Typeflag { 58 case tar.TypeDir: 59 if err := tarFS.MkdirAll(entryPath, os.FileMode(header.Mode)); err != nil { 60 return nil, err 61 } 62 case tar.TypeReg: 63 writePath := fmt.Sprintf("%s/%s", filepath.Dir(path), entryPath) 64 p.debug.Log("Unpacking tar entry %s", writePath) 65 _ = tarFS.MkdirAll(filepath.Dir(writePath), fs.ModePerm) 66 content := []byte{} 67 writer := bytes.NewBuffer(content) 68 69 if err != nil { 70 return nil, err 71 } 72 for { 73 _, err := io.CopyN(writer, tr, 1024) 74 if err != nil { 75 if errors.Is(err, io.EOF) { 76 break 77 } 78 return nil, err 79 } 80 } 81 82 p.debug.Log("writing file contents to %s", writePath) 83 if err := tarFS.WriteFile(writePath, writer.Bytes(), fs.ModePerm); err != nil { 84 return nil, err 85 } 86 87 default: 88 return nil, fmt.Errorf("could not untar the section") 89 } 90 } 91 92 // remove the tarball from the fs 93 if err := tarFS.Remove(path); err != nil { 94 return nil, err 95 } 96 97 return tarFS, nil 98 }