@@ -2,20 +2,21 @@ package parser
22
33import (
44 "context"
5- "fmt"
65 "io"
6+ "slices"
77 "strings"
88
99 "github.com/moby/buildkit/frontend/dockerfile/instructions"
1010 "github.com/moby/buildkit/frontend/dockerfile/parser"
11+ "golang.org/x/xerrors"
1112
1213 "github.com/aquasecurity/trivy/pkg/iac/providers/dockerfile"
1314)
1415
1516func Parse (_ context.Context , r io.Reader , path string ) ([]* dockerfile.Dockerfile , error ) {
1617 parsed , err := parser .Parse (r )
1718 if err != nil {
18- return nil , fmt .Errorf ("dockerfile parse error: %w" , err )
19+ return nil , xerrors .Errorf ("dockerfile parse error: %w" , err )
1920 }
2021
2122 var (
@@ -28,9 +29,9 @@ func Parse(_ context.Context, r io.Reader, path string) ([]*dockerfile.Dockerfil
2829 for _ , child := range parsed .AST .Children {
2930 child .Value = strings .ToLower (child .Value )
3031
31- instr , err := instructions . ParseInstruction (child )
32+ instr , err := parseInstruction (child )
3233 if err != nil {
33- return nil , fmt .Errorf ("parse dockerfile instruction: %w" , err )
34+ return nil , xerrors .Errorf ("parse dockerfile instruction: %w" , err )
3435 }
3536
3637 if _ , ok := instr .(* instructions.Stage ); ok {
@@ -89,6 +90,39 @@ func Parse(_ context.Context, r io.Reader, path string) ([]*dockerfile.Dockerfil
8990 return []* dockerfile.Dockerfile {& parsedFile }, nil
9091}
9192
93+ func parseInstruction (child * parser.Node ) (any , error ) {
94+ for {
95+ instr , err := instructions .ParseInstruction (child )
96+ if err == nil {
97+ return instr , nil
98+ }
99+
100+ flagName := extractUnknownFlag (err .Error ())
101+ if flagName == "" {
102+ return nil , xerrors .Errorf ("parse instruction %q: %w" , child .Value , err )
103+ }
104+
105+ filtered := slices .DeleteFunc (child .Flags , func (flag string ) bool {
106+ return strings .HasPrefix (flag , flagName )
107+ })
108+
109+ if len (filtered ) == len (child .Flags ) {
110+ return nil , xerrors .Errorf ("cannot remove unknown flag %q from flags %v" , flagName , child .Flags )
111+ }
112+ child .Flags = filtered
113+ }
114+ }
115+
116+ func extractUnknownFlag (errMsg string ) string {
117+ after , ok := strings .CutPrefix (errMsg , "unknown flag: " )
118+ if ! ok {
119+ return ""
120+ }
121+
122+ flagName , _ , _ := strings .Cut (after , " " )
123+ return flagName
124+ }
125+
92126func originalFromHeredoc (node * parser.Node ) string {
93127 var sb strings.Builder
94128 sb .WriteString (node .Original )
0 commit comments