Skip to content

Commit 7b2b4d4

Browse files
authored
fix(misconf): map healthcheck start period flag to --start-period instead of --startPeriod (#9837)
Signed-off-by: nikpivkin <[email protected]>
1 parent f5bbb0b commit 7b2b4d4

File tree

5 files changed

+41
-12
lines changed

5 files changed

+41
-12
lines changed

pkg/fanal/analyzer/imgconf/dockerfile/dockerfile.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ func buildHealthcheckInstruction(health *v1.HealthConfig) string {
155155
timeout = fmt.Sprintf("--timeout=%s ", health.Timeout)
156156
}
157157
if health.StartPeriod != 0 {
158-
startPeriod = fmt.Sprintf("--startPeriod=%s ", health.StartPeriod)
158+
startPeriod = fmt.Sprintf("--start-period=%s ", health.StartPeriod)
159159
}
160160
if health.Retries != 0 {
161161
retries = fmt.Sprintf("--retries=%d ", health.Retries)

pkg/fanal/analyzer/imgconf/dockerfile/dockerfile_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ import (
66
"time"
77

88
v1 "github.com/google/go-containerregistry/pkg/v1"
9-
"github.com/moby/buildkit/frontend/dockerfile/parser"
109
"github.com/stretchr/testify/assert"
1110
"github.com/stretchr/testify/require"
1211

1312
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
1413
"github.com/aquasecurity/trivy/pkg/fanal/types"
14+
"github.com/aquasecurity/trivy/pkg/iac/scanners/dockerfile/parser"
1515
)
1616

1717
func Test_historyAnalyzer_Analyze(t *testing.T) {
@@ -384,7 +384,7 @@ func Test_ImageConfigToDockerfile(t *testing.T) {
384384
},
385385
},
386386
},
387-
expected: "HEALTHCHECK --interval=5m0s --timeout=3s --startPeriod=1s --retries=3 CMD curl -f http://localhost/ || exit 1\n",
387+
expected: "HEALTHCHECK --interval=5m0s --timeout=3s --start-period=1s --retries=3 CMD curl -f http://localhost/ || exit 1\n",
388388
},
389389
{
390390
name: "healthcheck instruction exec arguments directly",
@@ -474,7 +474,8 @@ ENTRYPOINT ["/bin/sh"]
474474
for _, tt := range tests {
475475
t.Run(tt.name, func(t *testing.T) {
476476
got := imageConfigToDockerfile(tt.input)
477-
_, err := parser.Parse(bytes.NewReader(got))
477+
p := parser.NewParser(parser.WithStrict())
478+
_, err := p.Parse(t.Context(), bytes.NewReader(got), "Dockerfile")
478479
require.NoError(t, err)
479480

480481
assert.Equal(t, tt.expected, string(got))

pkg/iac/scanners/dockerfile/parser/parser.go

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,30 @@ import (
1313
"github.com/aquasecurity/trivy/pkg/iac/providers/dockerfile"
1414
)
1515

16-
func Parse(_ context.Context, r io.Reader, path string) ([]*dockerfile.Dockerfile, error) {
16+
type Parser struct {
17+
strict bool
18+
}
19+
20+
type Option func(p *Parser)
21+
22+
// WithStrict returns a Parser option that enables strict parsing mode.
23+
// By default, the Parser runs in non-strict mode, where unknown flags are ignored.
24+
// Calling this option ensures that unknown flags cause an error.
25+
func WithStrict() Option {
26+
return func(p *Parser) {
27+
p.strict = true
28+
}
29+
}
30+
31+
func NewParser(opts ...Option) *Parser {
32+
p := &Parser{}
33+
for _, opt := range opts {
34+
opt(p)
35+
}
36+
return p
37+
}
38+
39+
func (p *Parser) Parse(_ context.Context, r io.Reader, path string) ([]*dockerfile.Dockerfile, error) {
1740
parsed, err := parser.Parse(r)
1841
if err != nil {
1942
return nil, xerrors.Errorf("dockerfile parse error: %w", err)
@@ -29,7 +52,7 @@ func Parse(_ context.Context, r io.Reader, path string) ([]*dockerfile.Dockerfil
2952
for _, child := range parsed.AST.Children {
3053
child.Value = strings.ToLower(child.Value)
3154

32-
instr, err := parseInstruction(child)
55+
instr, err := p.parseInstruction(child)
3356
if err != nil {
3457
return nil, xerrors.Errorf("parse dockerfile instruction: %w", err)
3558
}
@@ -90,11 +113,13 @@ func Parse(_ context.Context, r io.Reader, path string) ([]*dockerfile.Dockerfil
90113
return []*dockerfile.Dockerfile{&parsedFile}, nil
91114
}
92115

93-
func parseInstruction(child *parser.Node) (any, error) {
116+
func (p *Parser) parseInstruction(child *parser.Node) (any, error) {
94117
for {
95118
instr, err := instructions.ParseInstruction(child)
96119
if err == nil {
97120
return instr, nil
121+
} else if p.strict {
122+
return nil, xerrors.Errorf("parse instruction %q: %w", child.Value, err)
98123
}
99124

100125
flagName := extractUnknownFlag(err.Error())

pkg/iac/scanners/dockerfile/parser/parser_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ COPY . /app
1717
RUN make /app
1818
CMD python /app/app.py
1919
`
20-
21-
dfs, err := parser.Parse(t.Context(), strings.NewReader(input), "Dockerfile")
20+
p := parser.NewParser()
21+
dfs, err := p.Parse(t.Context(), strings.NewReader(input), "Dockerfile")
2222
require.NoError(t, err)
2323
require.Len(t, dfs, 1)
2424

@@ -65,7 +65,8 @@ RUN --baz --baz --network=host make /app
6565
ONBUILD RUN --foo make /app
6666
CMD python /app/app.py
6767
`
68-
dfs, err := parser.Parse(t.Context(), strings.NewReader(input), "Dockerfile")
68+
p := parser.NewParser()
69+
dfs, err := p.Parse(t.Context(), strings.NewReader(input), "Dockerfile")
6970
require.NoError(t, err)
7071
require.Len(t, dfs, 1)
7172

@@ -170,7 +171,8 @@ EOF`,
170171

171172
for _, tt := range tests {
172173
t.Run(tt.name, func(t *testing.T) {
173-
dfs, err := parser.Parse(t.Context(), strings.NewReader(tt.src), "Dockerfile")
174+
p := parser.NewParser()
175+
dfs, err := p.Parse(t.Context(), strings.NewReader(tt.src), "Dockerfile")
174176
require.NoError(t, err)
175177
require.Len(t, dfs, 1)
176178

pkg/iac/scanners/dockerfile/scanner.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ func NewScanner(opts ...options.ScannerOption) *generic.GenericScanner[*dockerfi
1212
defaultOpts := []options.ScannerOption{
1313
generic.WithSupportsInlineIgnore[*dockerfile.Dockerfile](true),
1414
}
15-
p := generic.ParseFunc[*dockerfile.Dockerfile](parser.Parse)
15+
16+
p := parser.NewParser()
1617
return generic.NewScanner("Dockerfile", types.SourceDockerfile, p, append(defaultOpts, opts...)...,
1718
)
1819
}

0 commit comments

Comments
 (0)