caddyfile: Loosen heredoc parsing (#5761)

This commit is contained in:
Francis Lavoie 2023-08-19 06:32:32 -04:00 committed by GitHub
parent 0a6d3333b2
commit 10053f7570
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 15 deletions

View file

@ -137,18 +137,28 @@ func (l *lexer) next() (bool, error) {
} }
// detect whether we have the start of a heredoc // detect whether we have the start of a heredoc
if !inHeredoc && !heredocEscaped && len(val) > 1 && string(val[:2]) == "<<" { if !(quoted || btQuoted) && !(inHeredoc || heredocEscaped) &&
if ch == '<' { len(val) > 1 && string(val[:2]) == "<<" {
return false, fmt.Errorf("too many '<' for heredoc on line #%d; only use two, for example <<END", l.line) // a space means it's just a regular token and not a heredoc
if ch == ' ' {
return makeToken(0), nil
} }
// skip CR, we only care about LF
if ch == '\r' { if ch == '\r' {
continue continue
} }
// after hitting a newline, we know that the heredoc marker // after hitting a newline, we know that the heredoc marker
// is the characters after the two << and the newline. // is the characters after the two << and the newline.
// we reset the val because the heredoc is syntax we don't // we reset the val because the heredoc is syntax we don't
// want to keep. // want to keep.
if ch == '\n' { if ch == '\n' {
// check if there's too many <
if string(val[:3]) == "<<<" {
return false, fmt.Errorf("too many '<' for heredoc on line #%d; only use two, for example <<END", l.line)
}
heredocMarker = string(val[2:]) heredocMarker = string(val[2:])
if !heredocMarkerRegexp.Match([]byte(heredocMarker)) { if !heredocMarkerRegexp.Match([]byte(heredocMarker)) {
return false, fmt.Errorf("heredoc marker on line #%d must contain only alpha-numeric characters, dashes and underscores; got '%s'", l.line, heredocMarker) return false, fmt.Errorf("heredoc marker on line #%d must contain only alpha-numeric characters, dashes and underscores; got '%s'", l.line, heredocMarker)

View file

@ -322,15 +322,59 @@ EOF same-line-arg
}, },
}, },
{ {
input: []byte(`heredoc <EOF input: []byte(`escaped-heredoc \<< >>`),
expected: []Token{
{Line: 1, Text: `escaped-heredoc`},
{Line: 1, Text: `<<`},
{Line: 1, Text: `>>`},
},
},
{
input: []byte(`not-a-heredoc <EOF
content content
EOF same-line-arg
`), `),
expected: []Token{ expected: []Token{
{Line: 1, Text: `heredoc`}, {Line: 1, Text: `not-a-heredoc`},
{Line: 1, Text: `<EOF`}, {Line: 1, Text: `<EOF`},
{Line: 2, Text: `content`}, {Line: 2, Text: `content`},
{Line: 3, Text: `EOF`}, },
},
{
input: []byte(`not-a-heredoc <<<EOF content`),
expected: []Token{
{Line: 1, Text: `not-a-heredoc`},
{Line: 1, Text: `<<<EOF`},
{Line: 1, Text: `content`},
},
},
{
input: []byte(`not-a-heredoc "<<" ">>"`),
expected: []Token{
{Line: 1, Text: `not-a-heredoc`},
{Line: 1, Text: `<<`},
{Line: 1, Text: `>>`},
},
},
{
input: []byte(`not-a-heredoc << >>`),
expected: []Token{
{Line: 1, Text: `not-a-heredoc`},
{Line: 1, Text: `<<`},
{Line: 1, Text: `>>`},
},
},
{
input: []byte(`not-a-heredoc <<HERE SAME LINE
content
HERE same-line-arg
`),
expected: []Token{
{Line: 1, Text: `not-a-heredoc`},
{Line: 1, Text: `<<HERE`},
{Line: 1, Text: `SAME`},
{Line: 1, Text: `LINE`},
{Line: 2, Text: `content`},
{Line: 3, Text: `HERE`},
{Line: 3, Text: `same-line-arg`}, {Line: 3, Text: `same-line-arg`},
}, },
}, },
@ -365,14 +409,6 @@ EOF same-line-arg
}, },
}, },
}, },
{
input: []byte(`heredoc <<HERE SAME LINE
content
HERE same-line-arg
`),
expectErr: true,
errorMessage: "heredoc marker on line #1 must contain only alpha-numeric characters, dashes and underscores; got 'HERE SAME LINE'",
},
{ {
input: []byte(`heredoc <<<EOF input: []byte(`heredoc <<<EOF
content content