diff options
author | Matthew Holt <[email protected]> | 2021-11-15 14:41:19 -0700 |
---|---|---|
committer | Matthew Holt <[email protected]> | 2021-11-15 14:41:19 -0700 |
commit | b47af6ef04f818f41932e4152836d43a9be8fe07 (patch) | |
tree | cb765ed2842b58ef954f741e95174b0053021ec0 /caddyconfig/caddyfile/parse.go | |
parent | e81369e2208e47d9650f9699ad8bc7692640b275 (diff) | |
download | caddy-b47af6ef04f818f41932e4152836d43a9be8fe07.tar.gz caddy-b47af6ef04f818f41932e4152836d43a9be8fe07.zip |
caddyfile: Copy input before parsing (fix #4422)
Diffstat (limited to 'caddyconfig/caddyfile/parse.go')
-rwxr-xr-x | caddyconfig/caddyfile/parse.go | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/caddyconfig/caddyfile/parse.go b/caddyconfig/caddyfile/parse.go index 8591759bc..1e694f9f5 100755 --- a/caddyconfig/caddyfile/parse.go +++ b/caddyconfig/caddyfile/parse.go @@ -37,7 +37,13 @@ import ( // Environment variables in {$ENVIRONMENT_VARIABLE} notation // will be replaced before parsing begins. func Parse(filename string, input []byte) ([]ServerBlock, error) { - tokens, err := allTokens(filename, input) + // unfortunately, we must copy the input because parsing must + // remain a read-only operation, but we have to expand environment + // variables before we parse, which changes the underlying array (#4422) + inputCopy := make([]byte, len(input)) + copy(inputCopy, input) + + tokens, err := allTokens(filename, inputCopy) if err != nil { return nil, err } @@ -51,7 +57,23 @@ func Parse(filename string, input []byte) ([]ServerBlock, error) { return p.parseAll() } +// allTokens lexes the entire input, but does not parse it. +// It returns all the tokens from the input, unstructured +// and in order. It may mutate input as it expands env vars. +func allTokens(filename string, input []byte) ([]Token, error) { + inputCopy, err := replaceEnvVars(input) + if err != nil { + return nil, err + } + tokens, err := Tokenize(inputCopy, filename) + if err != nil { + return nil, err + } + return tokens, nil +} + // replaceEnvVars replaces all occurrences of environment variables. +// It mutates the underlying array and returns the updated slice. func replaceEnvVars(input []byte) ([]byte, error) { var offset int for { @@ -96,21 +118,6 @@ func replaceEnvVars(input []byte) ([]byte, error) { return input, nil } -// allTokens lexes the entire input, but does not parse it. -// It returns all the tokens from the input, unstructured -// and in order. -func allTokens(filename string, input []byte) ([]Token, error) { - input, err := replaceEnvVars(input) - if err != nil { - return nil, err - } - tokens, err := Tokenize(input, filename) - if err != nil { - return nil, err - } - return tokens, nil -} - type parser struct { *Dispenser block ServerBlock // current server block being parsed |