mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-26 13:43:47 +03:00
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
This commit is contained in:
parent
5bd9c49042
commit
cee4441cb1
5 changed files with 99 additions and 5 deletions
|
@ -214,7 +214,7 @@ func (p *parser) addresses() error {
|
||||||
|
|
||||||
// special case: import directive replaces tokens during parse-time
|
// special case: import directive replaces tokens during parse-time
|
||||||
if tkn == "import" && p.isNewLine() {
|
if tkn == "import" && p.isNewLine() {
|
||||||
err := p.doImport()
|
err := p.doImport(0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -314,7 +314,7 @@ func (p *parser) directives() error {
|
||||||
|
|
||||||
// special case: import directive replaces tokens during parse-time
|
// special case: import directive replaces tokens during parse-time
|
||||||
if p.Val() == "import" {
|
if p.Val() == "import" {
|
||||||
err := p.doImport()
|
err := p.doImport(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -340,7 +340,7 @@ func (p *parser) directives() error {
|
||||||
// is on the token before where the import directive was. In
|
// is on the token before where the import directive was. In
|
||||||
// other words, call Next() to access the first token that was
|
// other words, call Next() to access the first token that was
|
||||||
// imported.
|
// imported.
|
||||||
func (p *parser) doImport() error {
|
func (p *parser) doImport(nesting int) error {
|
||||||
// syntax checks
|
// syntax checks
|
||||||
if !p.NextArg() {
|
if !p.NextArg() {
|
||||||
return p.ArgErr()
|
return p.ArgErr()
|
||||||
|
@ -443,10 +443,16 @@ func (p *parser) doImport() error {
|
||||||
// copy the tokens so we don't overwrite p.definedSnippets
|
// copy the tokens so we don't overwrite p.definedSnippets
|
||||||
tokensCopy := make([]Token, 0, len(importedTokens))
|
tokensCopy := make([]Token, 0, len(importedTokens))
|
||||||
|
|
||||||
|
var (
|
||||||
|
maybeSnippet bool
|
||||||
|
maybeSnippetId bool
|
||||||
|
index int
|
||||||
|
)
|
||||||
|
|
||||||
// run the argument replacer on the tokens
|
// run the argument replacer on the tokens
|
||||||
// golang for range slice return a copy of value
|
// golang for range slice return a copy of value
|
||||||
// similarly, append also copy 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
|
// set the token's file to refer to import directive line number and snippet name
|
||||||
if token.snippetName != "" {
|
if token.snippetName != "" {
|
||||||
token.updateFile(fmt.Sprintf("%s:%d (import %s)", token.File, p.Line(), 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()))
|
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))
|
foundVariadic, startIndex, endIndex := parseVariadic(token, len(args))
|
||||||
if foundVariadic {
|
if foundVariadic {
|
||||||
for _, arg := range args[startIndex:endIndex] {
|
for _, arg := range args[startIndex:endIndex] {
|
||||||
|
@ -553,7 +593,7 @@ func (p *parser) directive() error {
|
||||||
} else if p.Val() == "}" && p.nesting == 0 {
|
} else if p.Val() == "}" && p.nesting == 0 {
|
||||||
return p.Err("Unexpected '}' because no matching opening brace")
|
return p.Err("Unexpected '}' because no matching opening brace")
|
||||||
} else if p.Val() == "import" && p.isNewLine() {
|
} else if p.Val() == "import" && p.isNewLine() {
|
||||||
if err := p.doImport(); err != nil {
|
if err := p.doImport(1); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.cursor-- // cursor is advanced when we continue, so roll back one more
|
p.cursor-- // cursor is advanced when we continue, so roll back one more
|
||||||
|
|
|
@ -243,6 +243,27 @@ func TestImportErrorLine(t *testing.T) {
|
||||||
return err != nil && strings.Contains(err.Error(), "Caddyfile:5 (import t1):2")
|
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{
|
adapter := caddyfile.Adapter{
|
||||||
ServerType: ServerType{},
|
ServerType: ServerType{},
|
||||||
|
|
9
caddyconfig/httpcaddyfile/testdata/import_variadic.txt
vendored
Normal file
9
caddyconfig/httpcaddyfile/testdata/import_variadic.txt
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
(t2) {
|
||||||
|
respond 200 {
|
||||||
|
body {args[:]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:8082 {
|
||||||
|
import t2 false
|
||||||
|
}
|
9
caddyconfig/httpcaddyfile/testdata/import_variadic_snippet.txt
vendored
Normal file
9
caddyconfig/httpcaddyfile/testdata/import_variadic_snippet.txt
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
(t1) {
|
||||||
|
respond 200 {
|
||||||
|
body {args[:]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:8081 {
|
||||||
|
import t1 false
|
||||||
|
}
|
15
caddyconfig/httpcaddyfile/testdata/import_variadic_with_import.txt
vendored
Normal file
15
caddyconfig/httpcaddyfile/testdata/import_variadic_with_import.txt
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
(t1) {
|
||||||
|
respond 200 {
|
||||||
|
body {args[:]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:8081 {
|
||||||
|
import t1 false
|
||||||
|
}
|
||||||
|
|
||||||
|
import import_variadic.txt
|
||||||
|
|
||||||
|
:8083 {
|
||||||
|
import t2 true
|
||||||
|
}
|
Loading…
Reference in a new issue