builder: fix processing of invalid substitusion syntax

The builder did not detect syntax errors in substitusions in the
Dockerfile, causing those values to be processed incorrectly instead of
producing an error.

Example 1: missing `}`

    docker build --no-cache -<<'EOF'
    FROM busybox
    ARG var=${aaa:-bbb
    RUN echo $var
    EOF

Before:

    Step 3/3 : RUN echo $var
     ---> Running in f06571e77146
    bbb

After:

    Step 2/3 : ARG var=${aaa:-bbb
    failed to process "${aaa:-bbb": syntax error: missing '}'

Example 2: missing closing `}`, no default value

    docker build --no-cache -<<'EOF'
    FROM busybox
    ARG var=${aaa
    RUN echo $var
    EOF

Before:

    Step 2/3 : ARG var=${aaa
    failed to process "${aaa": missing ':' in substitution

After:

    Step 2/3 : ARG var=${aaa
    failed to process "${aaa": syntax error: missing '}'

Example 3: double opening bracket (`{`)

    docker build --no-cache -<<'EOF'
    FROM busybox
    ARG var=${{aaa:-bbb}
    RUN echo $var
    EOF

Before:

    Step 2/3 : ARG var=${{aaa:-bbb}
    failed to process "${{aaa:-bbb}": missing ':' in substitution

After:

    Step 2/3 : ARG var=${{aaa:-bbb}
    failed to process "${{aaa:-bbb}": syntax error: bad substitution

Example 4: double opening bracket (`{`), no default value

    docker build --no-cache -<<'EOF'
    FROM busybox
    ARG var=${{aaa}
    RUN echo $var
    EOF

Before:

    Step 2/3 : ARG var=${{aaa}
    failed to process "${{aaa}": missing ':' in substitution

After:

    Step 2/3 : ARG var=${{aaa}
    failed to process "${{aaa}": syntax error: bad substitution

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2018-05-23 16:31:49 +02:00
parent 9c2c887b12
commit 955a6ad95f
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
3 changed files with 27 additions and 6 deletions

View file

@ -119,3 +119,14 @@ A|안녕${XXX:-\$PWD:}xx | 안녕$PWD:xx
A|안녕${XXX:-\${PWD}z}xx | 안녕${PWDz}xx
A|$KOREAN | 한국어
A|안녕$KOREAN | 안녕한국어
A|${{aaa} | error
A|${aaa}} | }
A|${aaa | error
A|${{aaa:-bbb} | error
A|${aaa:-bbb}} | bbb}
A|${aaa:-bbb | error
A|${aaa:-bbb} | bbb
A|${aaa:-${bbb:-ccc}} | ccc
A|${aaa:-bbb ${foo} | error
A|${aaa:-bbb {foo} | bbb {foo

View file

@ -131,7 +131,7 @@ func (sw *shellWord) processStopOn(stopChar rune) (string, []string, error) {
if stopChar != scanner.EOF && ch == stopChar {
sw.scanner.Next()
break
return result.String(), words.getWords(), nil
}
if fn, ok := charFuncMapping[ch]; ok {
// Call special processing func for certain chars
@ -166,7 +166,9 @@ func (sw *shellWord) processStopOn(stopChar rune) (string, []string, error) {
result.WriteRune(ch)
}
}
if stopChar != scanner.EOF {
return "", []string{}, errors.Errorf("unexpected end of statement while looking for matching %s", string(stopChar))
}
return result.String(), words.getWords(), nil
}
@ -261,12 +263,17 @@ func (sw *shellWord) processDollar() (string, error) {
sw.scanner.Next()
name := sw.processName()
ch := sw.scanner.Peek()
if ch == '}' {
switch ch {
case '}':
// Normal ${xx} case
sw.scanner.Next()
return sw.getEnv(name), nil
}
if ch == ':' {
case '{':
// Invalid ${{xx} case
return "", errors.New("syntax error: bad substitution")
case scanner.EOF:
return "", errors.New("syntax error: missing '}'")
case ':':
// Special ${xx:...} format processing
// Yes it allows for recursive $'s in the ... spot
@ -275,6 +282,9 @@ func (sw *shellWord) processDollar() (string, error) {
word, _, err := sw.processStopOn('}')
if err != nil {
if sw.scanner.Peek() == scanner.EOF {
return "", errors.New("syntax error: missing '}'")
}
return "", err
}

View file

@ -53,7 +53,7 @@ func TestShellParser4EnvVars(t *testing.T) {
((platform == "U" || platform == "A") && runtime.GOOS != "windows") {
newWord, err := shlex.ProcessWord(source, envs)
if expected == "error" {
assert.Check(t, is.ErrorContains(err, ""))
assert.Check(t, is.ErrorContains(err, ""), "input: %q, result: %q", source, newWord)
} else {
assert.Check(t, err)
assert.Check(t, is.Equal(newWord, expected))