Skip to content

Commit

Permalink
Merge pull request #1559 from thaJeztah/fix_trailing_escape
Browse files Browse the repository at this point in the history
Dockerfile: fix parsing of trailing backslash
  • Loading branch information
tiborvass committed Oct 29, 2020
2 parents a4f17f9 + cc7a3de commit 6b1c950
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 5 deletions.
20 changes: 16 additions & 4 deletions frontend/dockerfile/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,25 @@ type directives struct {
seen map[string]struct{} // Whether the escape directive has been seen
}

// setEscapeToken sets the default token for escaping characters in a Dockerfile.
// setEscapeToken sets the default token for escaping characters and as line-
// continuation token in a Dockerfile. Only ` (backtick) and \ (backslash) are
// allowed as token.
func (d *directives) setEscapeToken(s string) error {
if s != "`" && s != "\\" {
if s != "`" && s != `\` {
return errors.Errorf("invalid escape token '%s' does not match ` or \\", s)
}
d.escapeToken = rune(s[0])
d.lineContinuationRegex = regexp.MustCompile(`\` + s + `[ \t]*$`)
// The escape token is used both to escape characters in a line and as line
// continuation token. If it's the last non-whitespace token, it is used as
// line-continuation token, *unless* preceded by an escape-token.
//
// The second branch in the regular expression handles line-continuation
// tokens on their own line, which don't have any character preceding them.
//
// Due to Go lacking negative look-ahead matching, this regular expression
// does not currently handle a line-continuation token preceded by an *escaped*
// escape-token ("foo \\\").
d.lineContinuationRegex = regexp.MustCompile(`([^\` + s + `])\` + s + `[ \t]*$|^\` + s + `[ \t]*$`)
return nil
}

Expand Down Expand Up @@ -339,7 +351,7 @@ var utf8bom = []byte{0xEF, 0xBB, 0xBF}

func trimContinuationCharacter(line string, d *directives) (string, bool) {
if d.lineContinuationRegex.MatchString(line) {
line = d.lineContinuationRegex.ReplaceAllString(line, "")
line = d.lineContinuationRegex.ReplaceAllString(line, "$1")
return line, false
}
return line, true
Expand Down
2 changes: 1 addition & 1 deletion frontend/dockerfile/parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func TestParseCases(t *testing.T) {
// CRLF --> CR to match Unix behavior
content = bytes.Replace(content, []byte{'\x0d', '\x0a'}, []byte{'\x0a'}, -1)
}
require.Equal(t, result.AST.Dump()+"\n", string(content), dockerfile)
require.Equal(t, string(content), result.AST.Dump()+"\n", dockerfile)
})
}
}
Expand Down
17 changes: 17 additions & 0 deletions frontend/dockerfile/parser/testfiles/trailing-backslash/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# https://github.com/docker/for-win/issues/5254

FROM hello-world

ENV A path
ENV B another\\path
ENV C trailing\\backslash\\
ENV D This should not be appended to C
ENV E hello\
\
world
ENV F hello\
\
world
ENV G hello \
\
world
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
(from "hello-world")
(env "A" "path")
(env "B" "another\\\\path")
(env "C" "trailing\\\\backslash\\\\")
(env "D" "This should not be appended to C")
(env "E" "helloworld")
(env "F" "hello world")
(env "G" "hello world")

0 comments on commit 6b1c950

Please sign in to comment.