Skip to content

Commit 267a970

Browse files
fix(misconf): wrap legacy ENV values in quotes to preserve spaces (#9497)
Signed-off-by: nikpivkin <[email protected]> Co-authored-by: DmitriyLewen <[email protected]>
1 parent 842ebdc commit 267a970

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,10 @@ func imageConfigToDockerfile(cfg *v1.ConfigFile) []byte {
103103
case strings.HasPrefix(h.CreatedBy, "HEALTHCHECK"):
104104
// HEALTHCHECK instruction
105105
createdBy = buildHealthcheckInstruction(cfg.Config.Healthcheck)
106+
case strings.HasPrefix(h.CreatedBy, "ENV"):
107+
createdBy = restoreEnvLine(h.CreatedBy)
106108
default:
107-
for _, prefix := range []string{"ARG", "ENV", "ENTRYPOINT"} {
109+
for _, prefix := range []string{"ARG", "ENTRYPOINT"} {
108110
if strings.HasPrefix(h.CreatedBy, prefix) {
109111
createdBy = h.CreatedBy
110112
break
@@ -169,6 +171,22 @@ func normalizeCopyCreatedBy(input string) string {
169171
return copyInRe.ReplaceAllString(input, `$1 `)
170172
}
171173

174+
// restoreEnvLine normalizes a Dockerfile ENV instruction from image history.
175+
//
176+
// Legacy Dockerfiles may use ENV in the form: "ENV key val1 val2".
177+
// Docker stores this in image history as: "ENV key=val1 val2".
178+
// This can cause parsing errors, because extra tokens are treated as separate keys.
179+
// restoreEnvLine converts such lines into a valid `ENV <key>="<value>"` format
180+
// and wraps the value in quotes to preserve internal spaces and tabs.
181+
// e.g. `ENV tags=latest v0.0.0` -> `ENV key="latest v0.0.0"`
182+
func restoreEnvLine(createdBy string) string {
183+
k, v, ok := strings.Cut(createdBy, "=")
184+
if !ok {
185+
return createdBy
186+
}
187+
return fmt.Sprintf("%s=%q", k, v)
188+
}
189+
172190
func (a *historyAnalyzer) Required(_ types.OS) bool {
173191
return true
174192
}

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ func Test_ImageConfigToDockerfile(t *testing.T) {
430430
},
431431
},
432432
expected: `ARG TAG=latest
433-
ENV TAG=latest
433+
ENV TAG="latest"
434434
ENTRYPOINT ["/bin/sh" "-c" "echo test"]
435435
`,
436436
},
@@ -458,6 +458,17 @@ HEALTHCHECK NONE
458458
ENTRYPOINT ["/bin/sh"]
459459
`,
460460
},
461+
{
462+
name: "legacy env format",
463+
input: &v1.ConfigFile{
464+
History: []v1.History{
465+
{
466+
CreatedBy: "ENV TEST=foo bar",
467+
},
468+
},
469+
},
470+
expected: "ENV TEST=\"foo bar\"\n",
471+
},
461472
}
462473

463474
for _, tt := range tests {

0 commit comments

Comments
 (0)