Skip to content

Commit 471c5af

Browse files
authored
fix: race condition introduced in 04fdc0c (#2180)
Fix issue introduced in 04fdc0c
1 parent 24d6c99 commit 471c5af

4 files changed

Lines changed: 41 additions & 28 deletions

File tree

caddy/module.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,12 @@ func (f *FrankenPHPModule) Provision(ctx caddy.Context) error {
118118
if len(f.SplitPath) == 0 {
119119
f.SplitPath = []string{".php"}
120120
}
121-
f.requestOptions = append(f.requestOptions, frankenphp.WithRequestSplitPath(f.SplitPath))
121+
122+
if opt, err := frankenphp.WithRequestSplitPath(f.SplitPath); err == nil {
123+
f.requestOptions = append(f.requestOptions, opt)
124+
} else {
125+
f.requestOptions = append(f.requestOptions, opt)
126+
}
122127

123128
if f.ResolveRootSymlink == nil {
124129
rrs := true
@@ -188,6 +193,10 @@ func (f *FrankenPHPModule) ServeHTTP(w http.ResponseWriter, r *http.Request, _ c
188193
repl := ctx.Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
189194

190195
documentRoot := f.resolvedDocumentRoot
196+
197+
opts := make([]frankenphp.RequestOption, 0, len(f.requestOptions)+4)
198+
opts = append(opts, f.requestOptions...)
199+
191200
if documentRoot == "" {
192201
documentRoot = repl.ReplaceKnown(f.Root, "")
193202
if documentRoot == "" && frankenphp.EmbeddedAppPath != "" {
@@ -197,7 +206,7 @@ func (f *FrankenPHPModule) ServeHTTP(w http.ResponseWriter, r *http.Request, _ c
197206
// If we do not have a resolved document root, then we cannot resolve the symlink of our cwd because it may
198207
// resolve to a different directory than the one we are currently in.
199208
// This is especially important if there are workers running.
200-
f.requestOptions = append(f.requestOptions, frankenphp.WithRequestDocumentRoot(documentRoot, false))
209+
opts = append(opts, frankenphp.WithRequestDocumentRoot(documentRoot, false))
201210
}
202211

203212
if f.preparedEnvNeedsReplacement {
@@ -206,7 +215,7 @@ func (f *FrankenPHPModule) ServeHTTP(w http.ResponseWriter, r *http.Request, _ c
206215
env[k] = repl.ReplaceKnown(v, "")
207216
}
208217

209-
f.requestOptions = append(f.requestOptions, frankenphp.WithRequestPreparedEnv(env))
218+
opts = append(opts, frankenphp.WithRequestPreparedEnv(env))
210219
}
211220

212221
workerName := ""
@@ -220,7 +229,7 @@ func (f *FrankenPHPModule) ServeHTTP(w http.ResponseWriter, r *http.Request, _ c
220229
fr, err := frankenphp.NewRequestWithContext(
221230
r,
222231
append(
223-
f.requestOptions,
232+
opts,
224233
frankenphp.WithOriginalRequest(&origReq),
225234
frankenphp.WithWorkerName(workerName),
226235
)...,

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ require (
1212
github.com/prometheus/client_golang v1.23.2
1313
github.com/stretchr/testify v1.11.1
1414
golang.org/x/net v0.49.0
15+
golang.org/x/text v0.33.0
1516
)
1617

1718
require (
@@ -60,7 +61,6 @@ require (
6061
go.yaml.in/yaml/v3 v3.0.4 // indirect
6162
golang.org/x/crypto v0.47.0 // indirect
6263
golang.org/x/sys v0.40.0 // indirect
63-
golang.org/x/text v0.33.0 // indirect
6464
google.golang.org/protobuf v1.36.11 // indirect
6565
gopkg.in/yaml.v3 v3.0.1 // indirect
6666
)
Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -82,34 +82,34 @@ func WithRequestResolvedDocumentRoot(documentRoot string) RequestOption {
8282
// Future enhancements should be careful to avoid CVE-2019-11043,
8383
// which can be mitigated with use of a try_files-like behavior
8484
// that 404s if the FastCGI path info is not found.
85-
func WithRequestSplitPath(splitPath []string) RequestOption {
86-
return func(o *frankenPHPContext) error {
87-
var b strings.Builder
88-
89-
for i, split := range splitPath {
90-
b.Grow(len(split))
91-
92-
for j := 0; j < len(split); j++ {
93-
c := split[j]
94-
if c >= utf8.RuneSelf {
95-
return ErrInvalidSplitPath
96-
}
97-
98-
if 'A' <= c && c <= 'Z' {
99-
b.WriteByte(c + 'a' - 'A')
100-
} else {
101-
b.WriteByte(c)
102-
}
85+
func WithRequestSplitPath(splitPath []string) (RequestOption, error) {
86+
var b strings.Builder
87+
88+
for i, split := range splitPath {
89+
b.Grow(len(split))
90+
91+
for j := 0; j < len(split); j++ {
92+
c := split[j]
93+
if c >= utf8.RuneSelf {
94+
return nil, ErrInvalidSplitPath
10395
}
10496

105-
splitPath[i] = b.String()
106-
b.Reset()
97+
if 'A' <= c && c <= 'Z' {
98+
b.WriteByte(c + 'a' - 'A')
99+
} else {
100+
b.WriteByte(c)
101+
}
107102
}
108103

104+
splitPath[i] = b.String()
105+
b.Reset()
106+
}
107+
108+
return func(o *frankenPHPContext) error {
109109
o.splitPath = splitPath
110110

111111
return nil
112-
}
112+
}, nil
113113
}
114114

115115
type PreparedEnv = map[string]string
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
)
99

1010
func TestWithRequestSplitPath(t *testing.T) {
11+
t.Parallel()
12+
1113
tests := []struct {
1214
name string
1315
splitPath []string
@@ -52,9 +54,10 @@ func TestWithRequestSplitPath(t *testing.T) {
5254

5355
for _, tt := range tests {
5456
t.Run(tt.name, func(t *testing.T) {
57+
t.Parallel()
58+
5559
ctx := &frankenPHPContext{}
56-
opt := WithRequestSplitPath(tt.splitPath)
57-
err := opt(ctx)
60+
opt, err := WithRequestSplitPath(tt.splitPath)
5861

5962
if tt.wantErr != nil {
6063
require.ErrorIs(t, err, tt.wantErr)
@@ -63,6 +66,7 @@ func TestWithRequestSplitPath(t *testing.T) {
6366
}
6467

6568
require.NoError(t, err)
69+
require.NoError(t, opt(ctx))
6670
assert.Equal(t, tt.wantSplitPath, ctx.splitPath)
6771
})
6872
}

0 commit comments

Comments
 (0)