Skip to content

Commit

Permalink
Merge pull request #850 from cvgw/u/cgwippern/847_empty_arg_bug
Browse files Browse the repository at this point in the history
Fix quote strip behavior for ARG values
  • Loading branch information
tejal29 authored Nov 14, 2019
2 parents 907ae25 + 006b499 commit b5fd556
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 14 deletions.
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

0 comments on commit b5fd556

Please sign in to comment.