@marcel91200 / caddy Mirror · read-only / commits / 10053f75
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 12, 23:15 UTC

caddyfile: Loosen heredoc parsing (#5761)

Francis Lavoie committed Aug 19, 2023 at 06:32 UTC 10053f7570b113d41c5a5ba40e6c457ab0784ef5
2 files changed +61 -15
caddyconfig/caddyfile/lexer.go
+13 -3
@@ -137,18 +137,28 @@ func (l *lexer) next() (bool, error) {
137 }
138
139 // detect whether we have the start of a heredoc
140 - if !inHeredoc && !heredocEscaped && len(val) > 1 && string(val[:2]) == "<<" {
141 - if ch == '<' {
142 - return false, fmt.Errorf("too many '<' for heredoc on line #%d; only use two, for example <<END", l.line)
140 + if !(quoted || btQuoted) && !(inHeredoc || heredocEscaped) &&
141 + len(val) > 1 && string(val[:2]) == "<<" {
142 + // a space means it's just a regular token and not a heredoc
143 + if ch == ' ' {
144 + return makeToken(0), nil
145 }
146 +
147 + // skip CR, we only care about LF
148 if ch == '\r' {
149 continue
150 }
151 +
152 // after hitting a newline, we know that the heredoc marker
153 // is the characters after the two << and the newline.
154 // we reset the val because the heredoc is syntax we don't
155 // want to keep.
156 if ch == '\n' {
157 + // check if there's too many <
158 + if string(val[:3]) == "<<<" {
159 + return false, fmt.Errorf("too many '<' for heredoc on line #%d; only use two, for example <<END", l.line)
160 + }
161 +
162 heredocMarker = string(val[2:])
163 if !heredocMarkerRegexp.Match([]byte(heredocMarker)) {
164 return false, fmt.Errorf("heredoc marker on line #%d must contain only alpha-numeric characters, dashes and underscores; got '%s'", l.line, heredocMarker)
caddyconfig/caddyfile/lexer_test.go
+48 -12
@@ -322,15 +322,59 @@ EOF same-line-arg
322 },
323 },
324 {
325 - input: []byte(`heredoc <EOF
325 + input: []byte(`escaped-heredoc \<< >>`),
326 + expected: []Token{
327 + {Line: 1, Text: `escaped-heredoc`},
328 + {Line: 1, Text: `<<`},
329 + {Line: 1, Text: `>>`},
330 + },
331 + },
332 + {
333 + input: []byte(`not-a-heredoc <EOF
334 content
327 - EOF same-line-arg
335 `),
336 expected: []Token{
330 - {Line: 1, Text: `heredoc`},
337 + {Line: 1, Text: `not-a-heredoc`},
338 {Line: 1, Text: `<EOF`},
339 {Line: 2, Text: `content`},
333 - {Line: 3, Text: `EOF`},
340 + },
341 + },
342 + {
343 + input: []byte(`not-a-heredoc <<<EOF content`),
344 + expected: []Token{
345 + {Line: 1, Text: `not-a-heredoc`},
346 + {Line: 1, Text: `<<<EOF`},
347 + {Line: 1, Text: `content`},
348 + },
349 + },
350 + {
351 + input: []byte(`not-a-heredoc "<<" ">>"`),
352 + expected: []Token{
353 + {Line: 1, Text: `not-a-heredoc`},
354 + {Line: 1, Text: `<<`},
355 + {Line: 1, Text: `>>`},
356 + },
357 + },
358 + {
359 + input: []byte(`not-a-heredoc << >>`),
360 + expected: []Token{
361 + {Line: 1, Text: `not-a-heredoc`},
362 + {Line: 1, Text: `<<`},
363 + {Line: 1, Text: `>>`},
364 + },
365 + },
366 + {
367 + input: []byte(`not-a-heredoc <<HERE SAME LINE
368 + content
369 + HERE same-line-arg
370 + `),
371 + expected: []Token{
372 + {Line: 1, Text: `not-a-heredoc`},
373 + {Line: 1, Text: `<<HERE`},
374 + {Line: 1, Text: `SAME`},
375 + {Line: 1, Text: `LINE`},
376 + {Line: 2, Text: `content`},
377 + {Line: 3, Text: `HERE`},
378 {Line: 3, Text: `same-line-arg`},
379 },
380 },
@@ -365,14 +409,6 @@ EOF same-line-arg
409 },
410 },
411 },
368 - {
369 - input: []byte(`heredoc <<HERE SAME LINE
370 - content
371 - HERE same-line-arg
372 - `),
373 - expectErr: true,
374 - errorMessage: "heredoc marker on line #1 must contain only alpha-numeric characters, dashes and underscores; got 'HERE SAME LINE'",
375 - },
412 {
413 input: []byte(`heredoc <<<EOF
414 content