summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWeidiDeng <weidi_deng@icloud.com>2023-05-23 05:36:55 +0800
committerGitHub <noreply@github.com>2023-05-22 15:36:55 -0600
commitcee4441cb1d485b38d728168a315cda5641d84fb (patch)
treeb024ba176895a72d31993e8c069626adfe46fac9
parent5bd9c49042112183f0902a7ce6252aebf58e1ac9 (diff)
caddyfile: Do not replace import tokens if they are part of a snippet (#5539)
* fix variadic placeholder in imported file which also imports * fix tests. * skip replacing args when imported token may be part of a snippet
-rw-r--r--caddyconfig/caddyfile/parse.go50
-rw-r--r--caddyconfig/httpcaddyfile/builtins_test.go21
-rw-r--r--caddyconfig/httpcaddyfile/testdata/import_variadic.txt9
-rw-r--r--caddyconfig/httpcaddyfile/testdata/import_variadic_snippet.txt9
-rw-r--r--caddyconfig/httpcaddyfile/testdata/import_variadic_with_import.txt15
5 files changed, 99 insertions, 5 deletions
diff --git a/caddyconfig/caddyfile/parse.go b/caddyconfig/caddyfile/parse.go
index 64d1062..5afdc21 100644
--- a/caddyconfig/caddyfile/parse.go
+++ b/caddyconfig/caddyfile/parse.go
@@ -214,7 +214,7 @@ func (p *parser) addresses() error {
// special case: import directive replaces tokens during parse-time
if tkn == "import" && p.isNewLine() {
- err := p.doImport()
+ err := p.doImport(0)
if err != nil {
return err
}
@@ -314,7 +314,7 @@ func (p *parser) directives() error {
// special case: import directive replaces tokens during parse-time
if p.Val() == "import" {
- err := p.doImport()
+ err := p.doImport(1)
if err != nil {
return err
}
@@ -340,7 +340,7 @@ func (p *parser) directives() error {
// is on the token before where the import directive was. In
// other words, call Next() to access the first token that was
// imported.
-func (p *parser) doImport() error {
+func (p *parser) doImport(nesting int) error {
// syntax checks
if !p.NextArg() {
return p.ArgErr()
@@ -443,10 +443,16 @@ func (p *parser) doImport() error {
// copy the tokens so we don't overwrite p.definedSnippets
tokensCopy := make([]Token, 0, len(importedTokens))
+ var (
+ maybeSnippet bool
+ maybeSnippetId bool
+ index int
+ )
+
// run the argument replacer on the tokens
// golang for range slice return a copy of value
// similarly, append also copy value
- for _, token := range importedTokens {
+ for i, token := range importedTokens {
// set the token's file to refer to import directive line number and snippet name
if token.snippetName != "" {
token.updateFile(fmt.Sprintf("%s:%d (import %s)", token.File, p.Line(), token.snippetName))
@@ -454,6 +460,40 @@ func (p *parser) doImport() error {
token.updateFile(fmt.Sprintf("%s:%d (import)", token.File, p.Line()))
}
+ // naive way of determine snippets, as snippets definition can only follow name + block
+ // format, won't check for nesting correctness or any other error, that's what parser does.
+ if !maybeSnippet && nesting == 0 {
+ // first of the line
+ if i == 0 || importedTokens[i-1].originalFile() != token.originalFile() || importedTokens[i-1].Line+importedTokens[i-1].NumLineBreaks() < token.Line {
+ index = 0
+ } else {
+ index++
+ }
+
+ if index == 0 && len(token.Text) >= 3 && strings.HasPrefix(token.Text, "(") && strings.HasSuffix(token.Text, ")") {
+ maybeSnippetId = true
+ }
+ }
+
+ switch token.Text {
+ case "{":
+ nesting++
+ if index == 1 && maybeSnippetId && nesting == 1 {
+ maybeSnippet = true
+ maybeSnippetId = false
+ }
+ case "}":
+ nesting--
+ if nesting == 0 && maybeSnippet {
+ maybeSnippet = false
+ }
+ }
+
+ if maybeSnippet {
+ tokensCopy = append(tokensCopy, token)
+ continue
+ }
+
foundVariadic, startIndex, endIndex := parseVariadic(token, len(args))
if foundVariadic {
for _, arg := range args[startIndex:endIndex] {
@@ -553,7 +593,7 @@ func (p *parser) directive() error {
} else if p.Val() == "}" && p.nesting == 0 {
return p.Err("Unexpected '}' because no matching opening brace")
} else if p.Val() == "import" && p.isNewLine() {
- if err := p.doImport(); err != nil {
+ if err := p.doImport(1); err != nil {
return err
}
p.cursor-- // cursor is advanced when we continue, so roll back one more
diff --git a/caddyconfig/httpcaddyfile/builtins_test.go b/caddyconfig/httpcaddyfile/builtins_test.go
index 6ae4b31..34b4124 100644
--- a/caddyconfig/httpcaddyfile/builtins_test.go
+++ b/caddyconfig/httpcaddyfile/builtins_test.go
@@ -243,6 +243,27 @@ func TestImportErrorLine(t *testing.T) {
return err != nil && strings.Contains(err.Error(), "Caddyfile:5 (import t1):2")
},
},
+ {
+ input: `
+ import testdata/import_variadic_snippet.txt
+ :8080 {
+ import t1 true
+ }`,
+ errorFunc: func(err error) bool {
+ return err == nil
+ },
+ },
+ {
+ input: `
+ import testdata/import_variadic_with_import.txt
+ :8080 {
+ import t1 true
+ import t2 true
+ }`,
+ errorFunc: func(err error) bool {
+ return err == nil
+ },
+ },
} {
adapter := caddyfile.Adapter{
ServerType: ServerType{},
diff --git a/caddyconfig/httpcaddyfile/testdata/import_variadic.txt b/caddyconfig/httpcaddyfile/testdata/import_variadic.txt
new file mode 100644
index 0000000..f1e50e0
--- /dev/null
+++ b/caddyconfig/httpcaddyfile/testdata/import_variadic.txt
@@ -0,0 +1,9 @@
+(t2) {
+ respond 200 {
+ body {args[:]}
+ }
+}
+
+:8082 {
+ import t2 false
+} \ No newline at end of file
diff --git a/caddyconfig/httpcaddyfile/testdata/import_variadic_snippet.txt b/caddyconfig/httpcaddyfile/testdata/import_variadic_snippet.txt
new file mode 100644
index 0000000..a02fcf9
--- /dev/null
+++ b/caddyconfig/httpcaddyfile/testdata/import_variadic_snippet.txt
@@ -0,0 +1,9 @@
+(t1) {
+ respond 200 {
+ body {args[:]}
+ }
+}
+
+:8081 {
+ import t1 false
+} \ No newline at end of file
diff --git a/caddyconfig/httpcaddyfile/testdata/import_variadic_with_import.txt b/caddyconfig/httpcaddyfile/testdata/import_variadic_with_import.txt
new file mode 100644
index 0000000..ab1b32d
--- /dev/null
+++ b/caddyconfig/httpcaddyfile/testdata/import_variadic_with_import.txt
@@ -0,0 +1,15 @@
+(t1) {
+ respond 200 {
+ body {args[:]}
+ }
+}
+
+:8081 {
+ import t1 false
+}
+
+import import_variadic.txt
+
+:8083 {
+ import t2 true
+} \ No newline at end of file