Skip to content
This repository was archived by the owner on Jun 3, 2025. It is now read-only.

Commit c5f9ea5

Browse files
committed
Fix quote strip behavior for ARG values
* fixes issue 847 * previous implementation did not properly parse blank values which were enclosed in quotes
1 parent 1d5e294 commit c5f9ea5

3 files changed

Lines changed: 64 additions & 14 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ARG VARIANT=""
2+
ARG VERSION=1
3+
FROM busybox${VARIANT}:1.3${VERSION}

pkg/dockerfile/dockerfile.go

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -123,23 +123,13 @@ func Parse(b []byte) ([]instructions.Stage, []instructions.ArgCommand, error) {
123123
// stripEnclosingQuotes removes quotes enclosing the value of each instructions.ArgCommand in a slice
124124
// if the quotes are escaped it leaves them
125125
func stripEnclosingQuotes(metaArgs []instructions.ArgCommand) ([]instructions.ArgCommand, error) {
126-
dbl := byte('"')
127-
sgl := byte('\'')
128-
129126
for i := range metaArgs {
130127
arg := metaArgs[i]
131128
v := arg.Value
132129
if v != nil {
133-
val := *v
134-
fmt.Printf("val %s\n", val)
135-
if (val[0] == dbl && val[len(val)-1] == dbl) || (val[0] == sgl && val[len(val)-1] == sgl) {
136-
val = val[1 : len(val)-1]
137-
} else if val[:2] == `\"` && val[len(val)-2:] == `\"` {
138-
continue
139-
} else if val[:2] == `\'` && val[len(val)-2:] == `\'` {
140-
continue
141-
} else if val[0] == dbl || val[0] == sgl || val[len(val)-1] == dbl || val[len(val)-1] == sgl {
142-
return nil, errors.New("quotes wrapping arg values must be matched")
130+
val, err := extractValFromQuotes(*v)
131+
if err != nil {
132+
return nil, err
143133
}
144134

145135
arg.Value = &val
@@ -149,6 +139,55 @@ func stripEnclosingQuotes(metaArgs []instructions.ArgCommand) ([]instructions.Ar
149139
return metaArgs, nil
150140
}
151141

142+
func extractValFromQuotes(val string) (string, error) {
143+
backSlash := byte('\\')
144+
if len(val) < 2 {
145+
return val, nil
146+
}
147+
148+
var leader string
149+
var tail string
150+
151+
switch char := val[0]; char {
152+
case '\'', '"':
153+
leader = string([]byte{char})
154+
case backSlash:
155+
switch char := val[1]; char {
156+
case '\'', '"':
157+
leader = string([]byte{backSlash, char})
158+
}
159+
}
160+
161+
// If the length of leader is greater than one then it must be an escaped
162+
// character.
163+
if len(leader) < 2 {
164+
switch char := val[len(val)-1]; char {
165+
case '\'', '"':
166+
tail = string([]byte{char})
167+
}
168+
} else {
169+
switch char := val[len(val)-2:]; char {
170+
case `\'`, `\"`:
171+
tail = char
172+
}
173+
}
174+
175+
if string(leader) != string(tail) {
176+
logrus.Infof("leader %s tail %s", leader, tail)
177+
return "", errors.New("quotes wrapping arg values must be matched")
178+
}
179+
180+
if leader == "" {
181+
return val, nil
182+
}
183+
184+
if len(leader) == 2 {
185+
return val, nil
186+
}
187+
188+
return val[1 : len(val)-1], nil
189+
}
190+
152191
// targetStage returns the index of the target stage kaniko is trying to build
153192
func targetStage(stages []instructions.Stage, target string) (int, error) {
154193
if target == "" {

pkg/dockerfile/dockerfile_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func Test_stripEnclosingQuotes(t *testing.T) {
118118
success: true,
119119
}, {
120120
name: "blank value with enclosing double quotes",
121-
inArgs: []instructions.ArgCommand{newArgCommand("MEOW", "\"\"")},
121+
inArgs: []instructions.ArgCommand{newArgCommand("MEOW", `""`)},
122122
expected: []string{""},
123123
success: true,
124124
}, {
@@ -144,6 +144,14 @@ func Test_stripEnclosingQuotes(t *testing.T) {
144144
},
145145
expected: []string{"Purr", "Mrow"},
146146
success: true,
147+
}, {
148+
name: "multiple values, one blank, one a single int",
149+
inArgs: []instructions.ArgCommand{
150+
newArgCommand("MEOW", `""`),
151+
newArgCommand("MEW", `1`),
152+
},
153+
expected: []string{"", "1"},
154+
success: true,
147155
}, {
148156
name: "no values",
149157
success: true,

0 commit comments

Comments
 (0)