aboutsummaryrefslogtreecommitdiffhomepage
path: root/caddyconfig/caddyfile/parse.go
diff options
context:
space:
mode:
authorMatthew Holt <[email protected]>2021-11-15 14:41:19 -0700
committerMatthew Holt <[email protected]>2021-11-15 14:41:19 -0700
commitb47af6ef04f818f41932e4152836d43a9be8fe07 (patch)
treecb765ed2842b58ef954f741e95174b0053021ec0 /caddyconfig/caddyfile/parse.go
parente81369e2208e47d9650f9699ad8bc7692640b275 (diff)
downloadcaddy-b47af6ef04f818f41932e4152836d43a9be8fe07.tar.gz
caddy-b47af6ef04f818f41932e4152836d43a9be8fe07.zip
caddyfile: Copy input before parsing (fix #4422)
Diffstat (limited to 'caddyconfig/caddyfile/parse.go')
-rwxr-xr-xcaddyconfig/caddyfile/parse.go39
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