A url item stored as javascript://%0aalert(1)%0a//x passed Url::to and reached <loc>, which sitemap.xsl renders as a link on the site origin. - The definitions form refuses, per row, a url that is not a path or an http(s) URL (classes.AllowedItemURL) and a urlPattern that is not a path (signpost.ValidItemPattern), keyed data.<i>.url / .urlPattern. - Generator.addItem drops a loc or alternate that is not http(s). - sitemap:import-winter drops such url items and clears such patterns with a report line; sitemap:import refuses such an entry.
85 lines
2.6 KiB
Go
85 lines
2.6 KiB
Go
package classes_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.golem15.com/golem15/sm-sitemap-plugin/classes"
|
|
)
|
|
|
|
// TestURLTo runs every case of testdata/urlto.json through URLTo and
|
|
// compares it with the line PHP's Url::to wrote to urlto.golden (SC-3), then
|
|
// pins the helpers built on it: BackendURL and URLPath.
|
|
func TestURLTo(t *testing.T) {
|
|
var in struct {
|
|
Root string `json:"root"`
|
|
URLs []*string `json:"urls"`
|
|
}
|
|
if err := json.Unmarshal(readTestdata(t, "urlto.json"), &in); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
want := strings.Split(strings.TrimSuffix(string(readTestdata(t, "urlto.golden")), "\n"), "\n")
|
|
if len(in.URLs) < 50 || len(want) != len(in.URLs) {
|
|
t.Fatalf("%d inputs, %d golden lines", len(in.URLs), len(want))
|
|
}
|
|
for i, u := range in.URLs {
|
|
path := "<null>"
|
|
input := ""
|
|
if u != nil {
|
|
path, input = *u, *u
|
|
}
|
|
if got := classes.URLTo(in.Root, input); got != want[i] {
|
|
t.Errorf("case %d URLTo(%q) = %q, PHP %q", i, path, got, want[i])
|
|
}
|
|
}
|
|
|
|
for _, tc := range []struct{ root, want string }{
|
|
{"https://api.ex.pl", "https://api.ex.pl"},
|
|
{"https://api.ex.pl/", "https://api.ex.pl"},
|
|
{"http://h:8080/base", "http://h:8080/base"},
|
|
} {
|
|
if got := classes.BackendURL(tc.root); got != tc.want {
|
|
t.Errorf("BackendURL(%q) = %q, want %q", tc.root, got, tc.want)
|
|
}
|
|
}
|
|
for raw, want := range map[string]string{
|
|
"https://h/a/b?x=1#f": "/a/b",
|
|
"https://h": "",
|
|
"https://h/": "/",
|
|
"/rel/path": "/rel/path",
|
|
"": "",
|
|
} {
|
|
if got := classes.URLPath(raw); got != want {
|
|
t.Errorf("URLPath(%q) = %q, want %q", raw, got, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestAllowedItemURL pins the save rule of a url item's address (CR-01).
|
|
func TestAllowedItemURL(t *testing.T) {
|
|
for u, want := range map[string]bool{
|
|
"": true,
|
|
"/": true,
|
|
"/about": true,
|
|
"about/team?x=1": true,
|
|
"https://example.test/a": true,
|
|
"HTTP://example.test/a": true,
|
|
"javascript://%0aalert(1)%0a//x": false,
|
|
"javascript:alert(1)": false,
|
|
"data:text/html,x": false,
|
|
"mailto:a@example.test": false,
|
|
"//evil.test/x": false,
|
|
`/\evil.test/x`: false,
|
|
`\\evil.test`: false,
|
|
"#top": false,
|
|
" /about": false,
|
|
"/about\n": false,
|
|
"java\tscript:alert(1)": false,
|
|
} {
|
|
if got := classes.AllowedItemURL(u); got != want {
|
|
t.Errorf("AllowedItemURL(%q) = %v, want %v", u, got, want)
|
|
}
|
|
}
|
|
}
|