@marcel91200 / caddy Mirror · read-only / commits / bbe1952a
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 13, 00:30 UTC

caddyfile: Fix comparing if two tokens are on the same line (#5626)

* fix comparing if two tokens are on the same line * compare tokens from copies when importing

WeidiDeng committed Jul 13, 2023 at 04:32 UTC bbe1952a59a196b7598c6488beb770ec38a70dfc
4 files changed +103 -25
caddyconfig/caddyfile/dispenser.go
+4 -24
@@ -106,7 +106,7 @@ func (d *Dispenser) nextOnSameLine() bool {
106 }
107 curr := d.tokens[d.cursor]
108 next := d.tokens[d.cursor+1]
109 - if curr.File == next.File && curr.Line+curr.NumLineBreaks() == next.Line {
109 + if !isNextOnNewLine(curr, next) {
110 d.cursor++
111 return true
112 }
@@ -127,7 +127,7 @@ func (d *Dispenser) NextLine() bool {
127 }
128 curr := d.tokens[d.cursor]
129 next := d.tokens[d.cursor+1]
130 - if curr.File != next.File || curr.Line+curr.NumLineBreaks() < next.Line {
130 + if isNextOnNewLine(curr, next) {
131 d.cursor++
132 return true
133 }
@@ -464,17 +464,7 @@ func (d *Dispenser) isNewLine() bool {
464
465 prev := d.tokens[d.cursor-1]
466 curr := d.tokens[d.cursor]
467 -
468 - // If the previous token is from a different file,
469 - // we can assume it's from a different line
470 - if prev.File != curr.File {
471 - return true
472 - }
473 -
474 - // If the previous token (incl line breaks) ends
475 - // on a line earlier than the current token,
476 - // then the current token is on a new line
477 - return prev.Line+prev.NumLineBreaks() < curr.Line
467 + return isNextOnNewLine(prev, curr)
468 }
469
470 // isNextOnNewLine determines whether the current token is on a different
@@ -490,15 +480,5 @@ func (d *Dispenser) isNextOnNewLine() bool {
480
481 curr := d.tokens[d.cursor]
482 next := d.tokens[d.cursor+1]
493 -
494 - // If the next token is from a different file,
495 - // we can assume it's from a different line
496 - if curr.File != next.File {
497 - return true
498 - }
499 -
500 - // If the current token (incl line breaks) ends
501 - // on a line earlier than the next token,
502 - // then the next token is on a new line
503 - return curr.Line+curr.NumLineBreaks() < next.Line
483 + return isNextOnNewLine(curr, next)
484 }
caddyconfig/caddyfile/lexer.go
+25
@@ -338,3 +338,28 @@ func (t Token) NumLineBreaks() int {
338 }
339
340 var heredocMarkerRegexp = regexp.MustCompile("^[A-Za-z0-9_-]+$")
341 +
342 +// isNextOnNewLine tests whether t2 is on a different line from t1
343 +func isNextOnNewLine(t1, t2 Token) bool {
344 + // If the second token is from a different file,
345 + // we can assume it's from a different line
346 + if t1.File != t2.File {
347 + return true
348 + }
349 +
350 + // If the second token is from a different import chain,
351 + // we can assume it's from a different line
352 + if len(t1.imports) != len(t2.imports) {
353 + return true
354 + }
355 + for i, im := range t1.imports {
356 + if im != t2.imports[i] {
357 + return true
358 + }
359 + }
360 +
361 + // If the first token (incl line breaks) ends
362 + // on a line earlier than the next token,
363 + // then the second token is on a new line
364 + return t1.Line+t1.NumLineBreaks() < t2.Line
365 +}
caddyconfig/caddyfile/parse.go
+1 -1
@@ -464,7 +464,7 @@ func (p *parser) doImport(nesting int) error {
464 // format, won't check for nesting correctness or any other error, that's what parser does.
465 if !maybeSnippet && nesting == 0 {
466 // first of the line
467 - if i == 0 || importedTokens[i-1].File != token.File || importedTokens[i-1].Line+importedTokens[i-1].NumLineBreaks() < token.Line {
467 + if i == 0 || isNextOnNewLine(tokensCopy[i-1], token) {
468 index = 0
469 } else {
470 index++
caddyconfig/httpcaddyfile/builtins_test.go
+73
@@ -277,3 +277,76 @@ func TestImportErrorLine(t *testing.T) {
277 }
278 }
279 }
280 +
281 +func TestNestedImport(t *testing.T) {
282 + for i, tc := range []struct {
283 + input string
284 + errorFunc func(err error) bool
285 + }{
286 + {
287 + input: `(t1) {
288 + respond {args[0]} {args[1]}
289 + }
290 +
291 + (t2) {
292 + import t1 {args[0]} 202
293 + }
294 +
295 + :8080 {
296 + handle {
297 + import t2 "foobar"
298 + }
299 + }`,
300 + errorFunc: func(err error) bool {
301 + return err == nil
302 + },
303 + },
304 + {
305 + input: `(t1) {
306 + respond {args[:]}
307 + }
308 +
309 + (t2) {
310 + import t1 {args[0]} {args[1]}
311 + }
312 +
313 + :8080 {
314 + handle {
315 + import t2 "foobar" 202
316 + }
317 + }`,
318 + errorFunc: func(err error) bool {
319 + return err == nil
320 + },
321 + },
322 + {
323 + input: `(t1) {
324 + respond {args[0]} {args[1]}
325 + }
326 +
327 + (t2) {
328 + import t1 {args[:]}
329 + }
330 +
331 + :8080 {
332 + handle {
333 + import t2 "foobar" 202
334 + }
335 + }`,
336 + errorFunc: func(err error) bool {
337 + return err == nil
338 + },
339 + },
340 + } {
341 + adapter := caddyfile.Adapter{
342 + ServerType: ServerType{},
343 + }
344 +
345 + _, _, err := adapter.Adapt([]byte(tc.input), nil)
346 +
347 + if !tc.errorFunc(err) {
348 + t.Errorf("Test %d error expectation failed, got %s", i, err)
349 + continue
350 + }
351 + }
352 +}