From 9654e9b6f80e1b931763c04400a19596e256c99a Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 25 May 2018 17:59:32 +0200 Subject: [PATCH] Add detection of "special parameters" for substitution Detect Special parameters as defined in http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_05_02 Treat these as parameters that are not set, instead of producing an error that a modifier is missing. Signed-off-by: Sebastiaan van Stijn --- builder/dockerfile/shell/envVarTest | 35 ++++++++++++++++++++++++++++ builder/dockerfile/shell/lex.go | 14 ++++++++++- builder/dockerfile/shell/lex_test.go | 8 +++---- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/builder/dockerfile/shell/envVarTest b/builder/dockerfile/shell/envVarTest index 005a54e99d..6071caebd2 100644 --- a/builder/dockerfile/shell/envVarTest +++ b/builder/dockerfile/shell/envVarTest @@ -174,3 +174,38 @@ A|$9 | A|${9} | A|${9:+bbb} | A|${9:-bbb} | bbb + +# Special parameters won't be set in the Dockerfile: +# http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_05_02 +A|$@ | +A|${@} | +A|${@:+bbb} | +A|${@:-bbb} | bbb +A|$* | +A|${*} | +A|${*:+bbb} | +A|${*:-bbb} | bbb +A|$# | +A|${#} | +A|${#:+bbb} | +A|${#:-bbb} | bbb +A|$? | +A|${?} | +A|${?:+bbb} | +A|${?:-bbb} | bbb +A|$- | +A|${-} | +A|${-:+bbb} | +A|${-:-bbb} | bbb +A|$$ | +A|${$} | +A|${$:+bbb} | +A|${$:-bbb} | bbb +A|$! | +A|${!} | +A|${!:+bbb} | +A|${!:-bbb} | bbb +A|$0 | +A|${0} | +A|${0:+bbb} | +A|${0:-bbb} | bbb diff --git a/builder/dockerfile/shell/lex.go b/builder/dockerfile/shell/lex.go index 983e5c0517..a51a2665aa 100644 --- a/builder/dockerfile/shell/lex.go +++ b/builder/dockerfile/shell/lex.go @@ -318,7 +318,7 @@ func (sw *shellWord) processName() string { for sw.scanner.Peek() != scanner.EOF { ch := sw.scanner.Peek() - if name.Len() == 0 && unicode.IsDigit(ch) { + if name.Len() == 0 && (unicode.IsDigit(ch) || isSpecialParam(ch)) { ch = sw.scanner.Next() return string(ch) } @@ -332,6 +332,18 @@ func (sw *shellWord) processName() string { return name.String() } +// isSpecialParam checks if the provided character is a special parameters, +// as defined in http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_05_02 +func isSpecialParam(char rune) bool { + switch char { + case '@', '*', '#', '?', '-', '$', '!', '0': + // Special parameters + // http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_05_02 + return true + } + return false +} + func (sw *shellWord) getEnv(name string) string { for _, env := range sw.envs { i := strings.Index(env, "=") diff --git a/builder/dockerfile/shell/lex_test.go b/builder/dockerfile/shell/lex_test.go index fa42c92989..4b30c32f2b 100644 --- a/builder/dockerfile/shell/lex_test.go +++ b/builder/dockerfile/shell/lex_test.go @@ -26,13 +26,11 @@ func TestShellParser4EnvVars(t *testing.T) { line := scanner.Text() lineCount++ - // Trim comments and blank lines - i := strings.Index(line, "#") - if i >= 0 { - line = line[:i] + // Skip comments and blank lines + if strings.HasPrefix(line, "#") { + continue } line = strings.TrimSpace(line) - if line == "" { continue }