mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-04 01:19:20 +08: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:
		@ -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
 | 
			
		||||
 | 
			
		||||
@ -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{},
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user