diff --git a/builder/support.go b/builder/support.go index 9ea439b53f301..a084190f2cb81 100644 --- a/builder/support.go +++ b/builder/support.go @@ -6,12 +6,17 @@ import ( ) var ( - TOKEN_ENV_INTERPOLATION = regexp.MustCompile(`(\\\\+|[^\\]|\b|\A)\$({?)([[:alnum:]_]+)(}?)`) + // `\\\\+|[^\\]|\b|\A` - match any number of "\\" (ie, properly-escaped backslashes), or a single non-backslash character, or a word boundary, or beginning-of-line + // `\$` - match literal $ + // `[[:alnum:]_]+` - match things like `$SOME_VAR` + // `{[[:alnum:]_]+}` - match things like `${SOME_VAR}` + tokenEnvInterpolation = regexp.MustCompile(`(\\\\+|[^\\]|\b|\A)\$([[:alnum:]_]+|{[[:alnum:]_]+})`) + // this intentionally punts on more exotic interpolations like ${SOME_VAR%suffix} and lets the shell handle those directly ) // handle environment replacement. Used in dispatcher. func (b *Builder) replaceEnv(str string) string { - for _, match := range TOKEN_ENV_INTERPOLATION.FindAllString(str, -1) { + for _, match := range tokenEnvInterpolation.FindAllString(str, -1) { match = match[strings.Index(match, "$"):] matchKey := strings.Trim(match, "${}") diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index 848dbfe4bdd8b..e456d579ab10f 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -2710,3 +2710,33 @@ func TestBuildRunShEntrypoint(t *testing.T) { logDone("build - entrypoint with /bin/echo running successfully") } + +func TestBuildExoticShellInterpolation(t *testing.T) { + name := "testbuildexoticshellinterpolation" + defer deleteImages(name) + + _, err := buildImage(name, ` + FROM busybox + + ENV SOME_VAR a.b.c + + RUN [ "$SOME_VAR" = 'a.b.c' ] + RUN [ "${SOME_VAR}" = 'a.b.c' ] + RUN [ "${SOME_VAR%.*}" = 'a.b' ] + RUN [ "${SOME_VAR%%.*}" = 'a' ] + RUN [ "${SOME_VAR#*.}" = 'b.c' ] + RUN [ "${SOME_VAR##*.}" = 'c' ] + RUN [ "${SOME_VAR/c/d}" = 'a.b.d' ] + RUN [ "${#SOME_VAR}" = '5' ] + + RUN [ "${SOME_UNSET_VAR:-$SOME_VAR}" = 'a.b.c' ] + RUN [ "${SOME_VAR:+Version: ${SOME_VAR}}" = 'Version: a.b.c' ] + RUN [ "${SOME_UNSET_VAR:+${SOME_VAR}}" = '' ] + RUN [ "${SOME_UNSET_VAR:-${SOME_VAR:-d.e.f}}" = 'a.b.c' ] + `, false) + if err != nil { + t.Fatal(err) + } + + logDone("build - exotic shell interpolation") +}