Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix quote strip behavior for ARG values #850

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions integration/dockerfiles/Dockerfile_test_arg_multi_empty_val
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ARG VARIANT=""
ARG VERSION=1
FROM busybox${VARIANT}:1.3${VERSION}
65 changes: 52 additions & 13 deletions pkg/dockerfile/dockerfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,23 +123,13 @@ func Parse(b []byte) ([]instructions.Stage, []instructions.ArgCommand, error) {
// stripEnclosingQuotes removes quotes enclosing the value of each instructions.ArgCommand in a slice
// if the quotes are escaped it leaves them
func stripEnclosingQuotes(metaArgs []instructions.ArgCommand) ([]instructions.ArgCommand, error) {
dbl := byte('"')
sgl := byte('\'')

for i := range metaArgs {
arg := metaArgs[i]
v := arg.Value
if v != nil {
val := *v
fmt.Printf("val %s\n", val)
if (val[0] == dbl && val[len(val)-1] == dbl) || (val[0] == sgl && val[len(val)-1] == sgl) {
val = val[1 : len(val)-1]
} else if val[:2] == `\"` && val[len(val)-2:] == `\"` {
continue
} else if val[:2] == `\'` && val[len(val)-2:] == `\'` {
continue
} else if val[0] == dbl || val[0] == sgl || val[len(val)-1] == dbl || val[len(val)-1] == sgl {
return nil, errors.New("quotes wrapping arg values must be matched")
val, err := extractValFromQuotes(*v)
if err != nil {
return nil, err
}

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

func extractValFromQuotes(val string) (string, error) {
backSlash := byte('\\')
if len(val) < 2 {
return val, nil
}

var leader string
var tail string

switch char := val[0]; char {
case '\'', '"':
leader = string([]byte{char})
case backSlash:
switch char := val[1]; char {
case '\'', '"':
leader = string([]byte{backSlash, char})
}
}

// If the length of leader is greater than one then it must be an escaped
// character.
if len(leader) < 2 {
switch char := val[len(val)-1]; char {
case '\'', '"':
tail = string([]byte{char})
}
} else {
switch char := val[len(val)-2:]; char {
case `\'`, `\"`:
tail = char
}
}

if leader != tail {
logrus.Infof("leader %s tail %s", leader, tail)
return "", errors.New("quotes wrapping arg values must be matched")
}

if leader == "" {
return val, nil
}

if len(leader) == 2 {
return val, nil
}

return val[1 : len(val)-1], nil
}

// targetStage returns the index of the target stage kaniko is trying to build
func targetStage(stages []instructions.Stage, target string) (int, error) {
if target == "" {
Expand Down
10 changes: 9 additions & 1 deletion pkg/dockerfile/dockerfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func Test_stripEnclosingQuotes(t *testing.T) {
success: true,
}, {
name: "blank value with enclosing double quotes",
inArgs: []instructions.ArgCommand{newArgCommand("MEOW", "\"\"")},
inArgs: []instructions.ArgCommand{newArgCommand("MEOW", `""`)},
expected: []string{""},
success: true,
}, {
Expand All @@ -144,6 +144,14 @@ func Test_stripEnclosingQuotes(t *testing.T) {
},
expected: []string{"Purr", "Mrow"},
success: true,
}, {
name: "multiple values, one blank, one a single int",
inArgs: []instructions.ArgCommand{
newArgCommand("MEOW", `""`),
newArgCommand("MEW", `1`),
},
expected: []string{"", "1"},
success: true,
}, {
name: "no values",
success: true,
Expand Down