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