@marcel91200 / caddy Mirror · read-only / commits / b47af6ef
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 14, 01:30 UTC

caddyfile: Copy input before parsing (fix #4422)

Matthew Holt committed Nov 15, 2021 at 14:41 UTC b47af6ef04f818f41932e4152836d43a9be8fe07
2 files changed +28 -16
caddyconfig/caddyfile/formatter_test.go
+5
@@ -179,6 +179,11 @@ d {
179 {$F}
180 }`,
181 },
182 + {
183 + description: "env var placeholders with port",
184 + input: `:{$PORT}`,
185 + expect: `:{$PORT}`,
186 + },
187 {
188 description: "comments",
189 input: `#a "\n"
caddyconfig/caddyfile/parse.go
+23 -16
@@ -37,7 +37,13 @@ import (
37 // Environment variables in {$ENVIRONMENT_VARIABLE} notation
38 // will be replaced before parsing begins.
39 func Parse(filename string, input []byte) ([]ServerBlock, error) {
40 - tokens, err := allTokens(filename, input)
40 + // unfortunately, we must copy the input because parsing must
41 + // remain a read-only operation, but we have to expand environment
42 + // variables before we parse, which changes the underlying array (#4422)
43 + inputCopy := make([]byte, len(input))
44 + copy(inputCopy, input)
45 +
46 + tokens, err := allTokens(filename, inputCopy)
47 if err != nil {
48 return nil, err
49 }
@@ -51,7 +57,23 @@ func Parse(filename string, input []byte) ([]ServerBlock, error) {
57 return p.parseAll()
58 }
59
60 +// allTokens lexes the entire input, but does not parse it.
61 +// It returns all the tokens from the input, unstructured
62 +// and in order. It may mutate input as it expands env vars.
63 +func allTokens(filename string, input []byte) ([]Token, error) {
64 + inputCopy, err := replaceEnvVars(input)
65 + if err != nil {
66 + return nil, err
67 + }
68 + tokens, err := Tokenize(inputCopy, filename)
69 + if err != nil {
70 + return nil, err
71 + }
72 + return tokens, nil
73 +}
74 +
75 // replaceEnvVars replaces all occurrences of environment variables.
76 +// It mutates the underlying array and returns the updated slice.
77 func replaceEnvVars(input []byte) ([]byte, error) {
78 var offset int
79 for {
@@ -96,21 +118,6 @@ func replaceEnvVars(input []byte) ([]byte, error) {
118 return input, nil
119 }
120
99 -// allTokens lexes the entire input, but does not parse it.
100 -// It returns all the tokens from the input, unstructured
101 -// and in order.
102 -func allTokens(filename string, input []byte) ([]Token, error) {
103 - input, err := replaceEnvVars(input)
104 - if err != nil {
105 - return nil, err
106 - }
107 - tokens, err := Tokenize(input, filename)
108 - if err != nil {
109 - return nil, err
110 - }
111 - return tokens, nil
112 -}
113 -
121 type parser struct {
122 *Dispenser
123 block ServerBlock // current server block being parsed