package classes import "testing" // TestAllowedURL pins the D-16 URL scheme rule shared by the admin save and // the public API: empty, a path, a fragment, or http, https, mailto and tel // in any case; never javascript:, data:, vbscript: or another scheme, and // never a URL with surrounding whitespace or control characters, which // browsers strip before reading the scheme. func TestAllowedURL(t *testing.T) { for _, url := range []string{ "", "/", "/blog/post?x=1#a", "#top", "//cdn.example.test/a", "http://example.test", "https://example.test/a", "HTTPS://EXAMPLE.TEST", "Http://x", "mailto:a@example.test", "MAILTO:a@example.test", "tel:+48123456", "TEL:123", } { if !AllowedURL(url) { t.Errorf("AllowedURL(%q) = false", url) } } for _, url := range []string{ "javascript:alert(1)", "JavaScript:alert(1)", "data:text/html,x", "vbscript:x", "ftp://x", "file:///etc/passwd", "blog", "example.test", "?q=1", "./a", "../a", "mailto", "https:x", "tel", " /a", "/a ", "\thttps://x", "https://x\n", "java\tscript:x", "/a\x00b", "/a\x7f", "\x01javascript:x", } { if AllowedURL(url) { t.Errorf("AllowedURL(%q) = true", url) } } for target, want := range map[string]bool{"": true, TargetSelf: true, TargetBlank: true, "_top": false, "_parent": false, "_BLANK": false, "frame": false} { if AllowedTarget(target) != want { t.Errorf("AllowedTarget(%q) != %v", target, want) } } }