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:
parent
9c2c887b12
commit
955a6ad95f
3 changed files with 27 additions and 6 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Add table
Reference in a new issue