57 lines
1.7 KiB
Go
57 lines
1.7 KiB
Go
package site
|
|
|
|
import "testing"
|
|
|
|
func TestSplitTilde(t *testing.T) {
|
|
tests := []struct {
|
|
path string
|
|
project string
|
|
rest string
|
|
ok bool
|
|
}{
|
|
{"/~proj", "proj", "", true},
|
|
{"/~proj/", "proj", "/", true},
|
|
{"/~proj/a/b", "proj", "/a/b", true},
|
|
{"/~proj/a/b/", "proj", "/a/b/", true},
|
|
{"/~proj//a", "proj", "//a", true},
|
|
{"/~p", "p", "", true},
|
|
{"/~proj/~other/x", "proj", "/~other/x", true},
|
|
// A percent-encoded traversal arrives here already decoded; the project
|
|
// still ends at the first slash, and Resolve cleans the remainder.
|
|
{"/~proj/../../etc/passwd", "proj", "/../../etc/passwd", true},
|
|
|
|
// Not a site request at all.
|
|
{"", "", "", false},
|
|
{"/", "", "", false},
|
|
{"/x", "", "", false},
|
|
{"/~", "", "", false},
|
|
{"/~/", "", "", false},
|
|
{"~proj/", "", "", false},
|
|
{"//~proj/", "", "", false},
|
|
{"/favicon.ico", "", "", false},
|
|
{"/api/v1/projects", "", "", false},
|
|
}
|
|
for _, tc := range tests {
|
|
project, rest, ok := splitTilde(tc.path)
|
|
if project != tc.project || rest != tc.rest || ok != tc.ok {
|
|
t.Errorf("splitTilde(%q) = (%q, %q, %v), want (%q, %q, %v)",
|
|
tc.path, project, rest, ok, tc.project, tc.rest, tc.ok)
|
|
}
|
|
}
|
|
}
|
|
|
|
// The project name never contains a slash, which is what makes "~" + name a
|
|
// single entry inside the webroot and keeps a redirect built from it inside the
|
|
// project's own prefix.
|
|
func TestSplitTildeProjectIsOneSegment(t *testing.T) {
|
|
for _, p := range []string{"/~a/b", "/~a//b", "/~a/../b", "/~a/b/c/d"} {
|
|
project, _, ok := splitTilde(p)
|
|
if !ok {
|
|
t.Fatalf("splitTilde(%q) refused a site path", p)
|
|
}
|
|
if project != "a" {
|
|
t.Errorf("splitTilde(%q) project = %q, want %q", p, project, "a")
|
|
}
|
|
}
|
|
}
|