github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/pkg/scanners/toml/parser/parser.go (about) 1 package parser 2 3 import ( 4 "context" 5 "io" 6 "io/fs" 7 "path/filepath" 8 9 "github.com/khulnasoft-lab/defsec/pkg/debug" 10 11 "github.com/khulnasoft-lab/defsec/pkg/scanners/options" 12 13 "github.com/BurntSushi/toml" 14 "github.com/khulnasoft-lab/defsec/pkg/detection" 15 ) 16 17 var _ options.ConfigurableParser = (*Parser)(nil) 18 19 type Parser struct { 20 debug debug.Logger 21 skipRequired bool 22 } 23 24 func (p *Parser) SetDebugWriter(writer io.Writer) { 25 p.debug = debug.New(writer, "toml", "parser") 26 } 27 28 func (p *Parser) SetSkipRequiredCheck(b bool) { 29 p.skipRequired = b 30 } 31 32 // New creates a new parser 33 func New(opts ...options.ParserOption) *Parser { 34 p := &Parser{} 35 for _, opt := range opts { 36 opt(p) 37 } 38 return p 39 } 40 41 func (p *Parser) ParseFS(ctx context.Context, target fs.FS, path string) (map[string]interface{}, error) { 42 43 files := make(map[string]interface{}) 44 if err := fs.WalkDir(target, filepath.ToSlash(path), func(path string, entry fs.DirEntry, err error) error { 45 select { 46 case <-ctx.Done(): 47 return ctx.Err() 48 default: 49 } 50 if err != nil { 51 return err 52 } 53 if entry.IsDir() { 54 return nil 55 } 56 if !p.Required(path) { 57 return nil 58 } 59 df, err := p.ParseFile(ctx, target, path) 60 if err != nil { 61 p.debug.Log("Parse error in '%s': %s", path, err) 62 return nil 63 } 64 files[path] = df 65 return nil 66 }); err != nil { 67 return nil, err 68 } 69 return files, nil 70 } 71 72 // ParseFile parses toml content from the provided filesystem path. 73 func (p *Parser) ParseFile(_ context.Context, fs fs.FS, path string) (interface{}, error) { 74 f, err := fs.Open(filepath.ToSlash(path)) 75 if err != nil { 76 return nil, err 77 } 78 defer func() { _ = f.Close() }() 79 var target interface{} 80 if _, err := toml.NewDecoder(f).Decode(&target); err != nil { 81 return nil, err 82 } 83 return target, nil 84 } 85 86 func (p *Parser) Required(path string) bool { 87 if p.skipRequired { 88 return true 89 } 90 return detection.IsType(path, nil, detection.FileTypeTOML) 91 }