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