Skip to content

Commit c30fef0

Browse files
authored
fix: ensure $SERVER["PHP_SELF"] always starts with a slash (#2172)
Closes #2166.
1 parent 46fa426 commit c30fef0

2 files changed

Lines changed: 43 additions & 1 deletion

File tree

cgi.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ func addKnownVariablesToServer(fc *frankenPHPContext, trackVarsArray *C.zval) {
145145
packCgiVariable(keys["REMOTE_PORT"], port),
146146
packCgiVariable(keys["DOCUMENT_ROOT"], fc.documentRoot),
147147
packCgiVariable(keys["PATH_INFO"], fc.pathInfo),
148-
packCgiVariable(keys["PHP_SELF"], request.URL.Path),
148+
packCgiVariable(keys["PHP_SELF"], ensureLeadingSlash(request.URL.Path)),
149149
packCgiVariable(keys["DOCUMENT_URI"], fc.docURI),
150150
packCgiVariable(keys["SCRIPT_FILENAME"], fc.scriptFilename),
151151
packCgiVariable(keys["SCRIPT_NAME"], fc.scriptName),
@@ -340,7 +340,16 @@ func sanitizedPathJoin(root, reqPath string) string {
340340

341341
const separator = string(filepath.Separator)
342342

343+
func ensureLeadingSlash(path string) string {
344+
if path == "" || path[0] == '/' {
345+
return path
346+
}
347+
348+
return "/" + path
349+
}
350+
343351
func toUnsafeChar(s string) *C.char {
344352
sData := unsafe.StringData(s)
353+
345354
return (*C.char)(unsafe.Pointer(sData))
346355
}

cgi_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package frankenphp
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestEnsureLeadingSlash(t *testing.T) {
10+
t.Parallel()
11+
12+
tests := []struct {
13+
input string
14+
expected string
15+
}{
16+
{"/index.php", "/index.php"},
17+
{"index.php", "/index.php"},
18+
{"/", "/"},
19+
{"", ""},
20+
{"/path/to/script.php", "/path/to/script.php"},
21+
{"path/to/script.php", "/path/to/script.php"},
22+
{"/index.php/path/info", "/index.php/path/info"},
23+
{"index.php/path/info", "/index.php/path/info"},
24+
}
25+
26+
for _, tt := range tests {
27+
t.Run(tt.input + "-" + tt.expected, func(t *testing.T) {
28+
t.Parallel()
29+
30+
assert.Equal(t, tt.expected, ensureLeadingSlash(tt.input), "ensureLeadingSlash(%q)", tt.input)
31+
})
32+
}
33+
}

0 commit comments

Comments
 (0)