diff --git a/lua/tests/gm_url/tests.lua b/lua/tests/gm_url/tests.lua new file mode 100644 index 0000000..f0fa51a --- /dev/null +++ b/lua/tests/gm_url/tests.lua @@ -0,0 +1 @@ +-- This is a dummy lua file diff --git a/lua/tests/gm_url/tests.yue b/lua/tests/gm_url/tests.yue new file mode 100644 index 0000000..75e3347 --- /dev/null +++ b/lua/tests/gm_url/tests.yue @@ -0,0 +1,66 @@ +import URL, decodeURIComponent from include "url.yue" +urltestdata = include "urltestdata.lua" + +-- First let's decode the test data +for test in *urltestdata + if istable(test) + for key, value in pairs test + if isstring value + test[key] = decodeURIComponent(value) + +cases = {} +for test in *urltestdata + if isstring(test) + cases[] = { name: test, func: -> } + continue + + prefix = (test.base and test.base != "about:blank") and "(#{test.base}) " or "" + name = "#{prefix}#{test.input} -> #{not test.failure and test.href or "failure"}" + func = -> + ok, url = pcall(URL, test.input, --[[test.base != "about:blank" and]] test.base) + if test.failure + if ok + print "expected failure but got: #{url.href}" + -- return -- fix later + expect(ok).to.beFalse() + return + + if not ok + print "failed to parse: #{url}" + expect(ok).to.beTrue() + + expect(url.protocol).to.eq(test.protocol) + + if test.password != "" + expect(url.password).to.eq(test.password) + + if test.username != "" + expect(url.username).to.eq(test.username) + + if test.hostname != "" + expect(url.hostname).to.eq(test.hostname) + + port = tonumber test.port + if port + expect(url.port).to.eq(port) + + expect(url.host).to.eq(test.host) + if test.origin and test.origin != "null" + expect(url.origin).to.eq(test.origin) + + if test.pathname != "" + expect(url.pathname).to.eq(test.pathname) + -- expect(url.search).to.eq(test.search) + -- expect(url.hash).to.eq(test.hash) + -- expect(url.href).to.eq(test.href) + + + return + + + cases[] = { :name, :func } + +return { + :cases, + groupName: "gm_url whatwg-url tests" +} diff --git a/lua/tests/gm_url/url.yue b/lua/tests/gm_url/url.yue new file mode 120000 index 0000000..cabd70b --- /dev/null +++ b/lua/tests/gm_url/url.yue @@ -0,0 +1 @@ +../../../url.yue \ No newline at end of file diff --git a/lua/tests/gm_url/urltestdata.lua b/lua/tests/gm_url/urltestdata.lua new file mode 100644 index 0000000..f9ef2a6 --- /dev/null +++ b/lua/tests/gm_url/urltestdata.lua @@ -0,0 +1,9816 @@ +return { + "See ../README.md for a description of the format.", + { + input = "http://example%09.%0Aorg", + base = "http://example.org/foo/bar", + href = "http://example.org/", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://user:pass@foo:21/bar;par?b#c", + base = "http://example.org/foo/bar", + href = "http://user:pass@foo:21/bar;par?b#c", + origin = "http://foo:21", + protocol = "http:", + username = "user", + password = "pass", + host = "foo:21", + hostname = "foo", + port = "21", + pathname = "/bar;par", + search = "?b", + hash = "#c", + }, + { + input = "https://test:@test", + base = nil, + href = "https://test@test/", + origin = "https://test", + protocol = "https:", + username = "test", + password = "", + host = "test", + hostname = "test", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "https://:@test", + base = nil, + href = "https://test/", + origin = "https://test", + protocol = "https:", + username = "", + password = "", + host = "test", + hostname = "test", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "non-special://test:@test/x", + base = nil, + href = "non-special://test@test/x", + origin = "null", + protocol = "non-special:", + username = "test", + password = "", + host = "test", + hostname = "test", + port = "", + pathname = "/x", + search = "", + hash = "", + }, + { + input = "non-special://:@test/x", + base = nil, + href = "non-special://test/x", + origin = "null", + protocol = "non-special:", + username = "", + password = "", + host = "test", + hostname = "test", + port = "", + pathname = "/x", + search = "", + hash = "", + }, + { + input = "http:foo.com", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/foo.com", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/foo.com", + search = "", + hash = "", + }, + { + input = "%09 :foo.com %0A", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/:foo.com", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/:foo.com", + search = "", + hash = "", + }, + { + input = " foo.com ", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/foo.com", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/foo.com", + search = "", + hash = "", + }, + { + input = "a:%09 foo.com", + base = "http://example.org/foo/bar", + href = "a: foo.com", + origin = "null", + protocol = "a:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = " foo.com", + search = "", + hash = "", + }, + { + input = "http://f:21/ b ? d # e ", + base = "http://example.org/foo/bar", + href = "http://f:21/%2520b%2520?%2520d%2520#%2520e", + origin = "http://f:21", + protocol = "http:", + username = "", + password = "", + host = "f:21", + hostname = "f", + port = "21", + pathname = "/%2520b%2520", + search = "?%2520d%2520", + hash = "#%2520e", + }, + { + input = "lolscheme:x x#x x", + base = nil, + href = "lolscheme:x x#x%2520x", + protocol = "lolscheme:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "x x", + search = "", + hash = "#x%2520x", + }, + { + input = "http://f:/c", + base = "http://example.org/foo/bar", + href = "http://f/c", + origin = "http://f", + protocol = "http:", + username = "", + password = "", + host = "f", + hostname = "f", + port = "", + pathname = "/c", + search = "", + hash = "", + }, + { + input = "http://f:0/c", + base = "http://example.org/foo/bar", + href = "http://f:0/c", + origin = "http://f:0", + protocol = "http:", + username = "", + password = "", + host = "f:0", + hostname = "f", + port = "0", + pathname = "/c", + search = "", + hash = "", + }, + { + input = "http://f:00000000000000/c", + base = "http://example.org/foo/bar", + href = "http://f:0/c", + origin = "http://f:0", + protocol = "http:", + username = "", + password = "", + host = "f:0", + hostname = "f", + port = "0", + pathname = "/c", + search = "", + hash = "", + }, + { + input = "http://f:00000000000000000000080/c", + base = "http://example.org/foo/bar", + href = "http://f/c", + origin = "http://f", + protocol = "http:", + username = "", + password = "", + host = "f", + hostname = "f", + port = "", + pathname = "/c", + search = "", + hash = "", + }, + { + input = "http://f:b/c", + base = "http://example.org/foo/bar", + failure = true, + }, + { + input = "http://f: /c", + base = "http://example.org/foo/bar", + failure = true, + }, + { + input = "http://f:%0A/c", + base = "http://example.org/foo/bar", + href = "http://f/c", + origin = "http://f", + protocol = "http:", + username = "", + password = "", + host = "f", + hostname = "f", + port = "", + pathname = "/c", + search = "", + hash = "", + }, + { + input = "http://f:fifty-two/c", + base = "http://example.org/foo/bar", + failure = true, + }, + { + input = "http://f:999999/c", + base = "http://example.org/foo/bar", + failure = true, + }, + { + input = "non-special://f:999999/c", + base = "http://example.org/foo/bar", + failure = true, + }, + { + input = "http://f: 21 / b ? d # e ", + base = "http://example.org/foo/bar", + failure = true, + }, + { + input = "", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/bar", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/bar", + search = "", + hash = "", + }, + { + input = " %09", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/bar", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/bar", + search = "", + hash = "", + }, + { + input = ":foo.com/", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/:foo.com/", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/:foo.com/", + search = "", + hash = "", + }, + { + input = ":foo.com%5C", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/:foo.com/", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/:foo.com/", + search = "", + hash = "", + }, + { + input = ":", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/:", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/:", + search = "", + hash = "", + }, + { + input = ":a", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/:a", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/:a", + search = "", + hash = "", + }, + { + input = ":/", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/:/", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/:/", + search = "", + hash = "", + }, + { + input = ":%5C", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/:/", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/:/", + search = "", + hash = "", + }, + { + input = ":#", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/:#", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/:", + search = "", + hash = "", + }, + { + input = "#", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/bar#", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/bar", + search = "", + hash = "", + }, + { + input = "#/", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/bar#/", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/bar", + search = "", + hash = "#/", + }, + { + input = "#%5C", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/bar#%5C", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/bar", + search = "", + hash = "#%5C", + }, + { + input = "#;?", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/bar#;?", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/bar", + search = "", + hash = "#;?", + }, + { + input = "?", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/bar?", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/bar", + search = "", + hash = "", + }, + { + input = "/", + base = "http://example.org/foo/bar", + href = "http://example.org/", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = ":23", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/:23", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/:23", + search = "", + hash = "", + }, + { + input = "/:23", + base = "http://example.org/foo/bar", + href = "http://example.org/:23", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/:23", + search = "", + hash = "", + }, + { + input = "%5Cx", + base = "http://example.org/foo/bar", + href = "http://example.org/x", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/x", + search = "", + hash = "", + }, + { + input = "%5C%5Cx%5Chello", + base = "http://example.org/foo/bar", + href = "http://x/hello", + origin = "http://x", + protocol = "http:", + username = "", + password = "", + host = "x", + hostname = "x", + port = "", + pathname = "/hello", + search = "", + hash = "", + }, + { + input = "::", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/::", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/::", + search = "", + hash = "", + }, + { + input = "::23", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/::23", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/::23", + search = "", + hash = "", + }, + { + input = "foo://", + base = "http://example.org/foo/bar", + href = "foo://", + origin = "null", + protocol = "foo:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "", + search = "", + hash = "", + }, + { + input = "http://a:b@c:29/d", + base = "http://example.org/foo/bar", + href = "http://a:b@c:29/d", + origin = "http://c:29", + protocol = "http:", + username = "a", + password = "b", + host = "c:29", + hostname = "c", + port = "29", + pathname = "/d", + search = "", + hash = "", + }, + { + input = "http::@c:29", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/:@c:29", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/:@c:29", + search = "", + hash = "", + }, + { + input = "http://&a:foo(b]c@d:2/", + base = "http://example.org/foo/bar", + href = "http://&a:foo(b%255Dc@d:2/", + origin = "http://d:2", + protocol = "http:", + username = "&a", + password = "foo(b%255Dc", + host = "d:2", + hostname = "d", + port = "2", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://::@c@d:2", + base = "http://example.org/foo/bar", + href = "http://:%253A%2540c@d:2/", + origin = "http://d:2", + protocol = "http:", + username = "", + password = "%253A%2540c", + host = "d:2", + hostname = "d", + port = "2", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://foo.com:b@d/", + base = "http://example.org/foo/bar", + href = "http://foo.com:b@d/", + origin = "http://d", + protocol = "http:", + username = "foo.com", + password = "b", + host = "d", + hostname = "d", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://foo.com/%5C@", + base = "http://example.org/foo/bar", + href = "http://foo.com//@", + origin = "http://foo.com", + protocol = "http:", + username = "", + password = "", + host = "foo.com", + hostname = "foo.com", + port = "", + pathname = "//@", + search = "", + hash = "", + }, + { + input = "http:%5C%5Cfoo.com%5C", + base = "http://example.org/foo/bar", + href = "http://foo.com/", + origin = "http://foo.com", + protocol = "http:", + username = "", + password = "", + host = "foo.com", + hostname = "foo.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http:%5C%5Ca%5Cb:c%5Cd@foo.com%5C", + base = "http://example.org/foo/bar", + href = "http://a/b:c/d@foo.com/", + origin = "http://a", + protocol = "http:", + username = "", + password = "", + host = "a", + hostname = "a", + port = "", + pathname = "/b:c/d@foo.com/", + search = "", + hash = "", + }, + { + input = "http://a:b@c%5C", + base = nil, + href = "http://a:b@c/", + origin = "http://c", + protocol = "http:", + username = "a", + password = "b", + host = "c", + hostname = "c", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "ws://a@b%5Cc", + base = nil, + href = "ws://a@b/c", + origin = "ws://b", + protocol = "ws:", + username = "a", + password = "", + host = "b", + hostname = "b", + port = "", + pathname = "/c", + search = "", + hash = "", + }, + { + input = "foo:/", + base = "http://example.org/foo/bar", + href = "foo:/", + origin = "null", + protocol = "foo:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "foo:/bar.com/", + base = "http://example.org/foo/bar", + href = "foo:/bar.com/", + origin = "null", + protocol = "foo:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/bar.com/", + search = "", + hash = "", + }, + { + input = "foo://///////", + base = "http://example.org/foo/bar", + href = "foo://///////", + origin = "null", + protocol = "foo:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "///////", + search = "", + hash = "", + }, + { + input = "foo://///////bar.com/", + base = "http://example.org/foo/bar", + href = "foo://///////bar.com/", + origin = "null", + protocol = "foo:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "///////bar.com/", + search = "", + hash = "", + }, + { + input = "foo:////://///", + base = "http://example.org/foo/bar", + href = "foo:////://///", + origin = "null", + protocol = "foo:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "//://///", + search = "", + hash = "", + }, + { + input = "c:/foo", + base = "http://example.org/foo/bar", + href = "c:/foo", + origin = "null", + protocol = "c:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/foo", + search = "", + hash = "", + }, + { + input = "//foo/bar", + base = "http://example.org/foo/bar", + href = "http://foo/bar", + origin = "http://foo", + protocol = "http:", + username = "", + password = "", + host = "foo", + hostname = "foo", + port = "", + pathname = "/bar", + search = "", + hash = "", + }, + { + input = "http://foo/path;a??e#f#g", + base = "http://example.org/foo/bar", + href = "http://foo/path;a??e#f#g", + origin = "http://foo", + protocol = "http:", + username = "", + password = "", + host = "foo", + hostname = "foo", + port = "", + pathname = "/path;a", + search = "??e", + hash = "#f#g", + }, + { + input = "http://foo/abcd?efgh?ijkl", + base = "http://example.org/foo/bar", + href = "http://foo/abcd?efgh?ijkl", + origin = "http://foo", + protocol = "http:", + username = "", + password = "", + host = "foo", + hostname = "foo", + port = "", + pathname = "/abcd", + search = "?efgh?ijkl", + hash = "", + }, + { + input = "http://foo/abcd#foo?bar", + base = "http://example.org/foo/bar", + href = "http://foo/abcd#foo?bar", + origin = "http://foo", + protocol = "http:", + username = "", + password = "", + host = "foo", + hostname = "foo", + port = "", + pathname = "/abcd", + search = "", + hash = "#foo?bar", + }, + { + input = "[61:24:74]:98", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/[61:24:74]:98", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/[61:24:74]:98", + search = "", + hash = "", + }, + { + input = "http:[61:27]/:foo", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/[61:27]/:foo", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/[61:27]/:foo", + search = "", + hash = "", + }, + { + input = "http://[1::2]:3:4", + base = "http://example.org/foo/bar", + failure = true, + }, + { + input = "http://2001::1", + base = "http://example.org/foo/bar", + failure = true, + }, + { + input = "http://2001::1]", + base = "http://example.org/foo/bar", + failure = true, + }, + { + input = "http://2001::1]:80", + base = "http://example.org/foo/bar", + failure = true, + }, + { + input = "http://[2001::1]", + base = "http://example.org/foo/bar", + href = "http://[2001::1]/", + origin = "http://[2001::1]", + protocol = "http:", + username = "", + password = "", + host = "[2001::1]", + hostname = "[2001::1]", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://[::127.0.0.1]", + base = "http://example.org/foo/bar", + href = "http://[::7f00:1]/", + origin = "http://[::7f00:1]", + protocol = "http:", + username = "", + password = "", + host = "[::7f00:1]", + hostname = "[::7f00:1]", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://[::127.0.0.1.]", + base = "http://example.org/foo/bar", + failure = true, + }, + { + input = "http://[0:0:0:0:0:0:13.1.68.3]", + base = "http://example.org/foo/bar", + href = "http://[::d01:4403]/", + origin = "http://[::d01:4403]", + protocol = "http:", + username = "", + password = "", + host = "[::d01:4403]", + hostname = "[::d01:4403]", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://[2001::1]:80", + base = "http://example.org/foo/bar", + href = "http://[2001::1]/", + origin = "http://[2001::1]", + protocol = "http:", + username = "", + password = "", + host = "[2001::1]", + hostname = "[2001::1]", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http:/example.com/", + base = "http://example.org/foo/bar", + href = "http://example.org/example.com/", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/example.com/", + search = "", + hash = "", + }, + { + input = "ftp:/example.com/", + base = "http://example.org/foo/bar", + href = "ftp://example.com/", + origin = "ftp://example.com", + protocol = "ftp:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "https:/example.com/", + base = "http://example.org/foo/bar", + href = "https://example.com/", + origin = "https://example.com", + protocol = "https:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "madeupscheme:/example.com/", + base = "http://example.org/foo/bar", + href = "madeupscheme:/example.com/", + origin = "null", + protocol = "madeupscheme:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/example.com/", + search = "", + hash = "", + }, + { + input = "file:/example.com/", + base = "http://example.org/foo/bar", + href = "file:///example.com/", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/example.com/", + search = "", + hash = "", + }, + { + input = "file://example:1/", + base = nil, + failure = true, + }, + { + input = "file://example:test/", + base = nil, + failure = true, + }, + { + input = "file://example%25/", + base = nil, + failure = true, + }, + { + input = "file://[example]/", + base = nil, + failure = true, + }, + { + input = "ftps:/example.com/", + base = "http://example.org/foo/bar", + href = "ftps:/example.com/", + origin = "null", + protocol = "ftps:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/example.com/", + search = "", + hash = "", + }, + { + input = "gopher:/example.com/", + base = "http://example.org/foo/bar", + href = "gopher:/example.com/", + origin = "null", + protocol = "gopher:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/example.com/", + search = "", + hash = "", + }, + { + input = "ws:/example.com/", + base = "http://example.org/foo/bar", + href = "ws://example.com/", + origin = "ws://example.com", + protocol = "ws:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "wss:/example.com/", + base = "http://example.org/foo/bar", + href = "wss://example.com/", + origin = "wss://example.com", + protocol = "wss:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "data:/example.com/", + base = "http://example.org/foo/bar", + href = "data:/example.com/", + origin = "null", + protocol = "data:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/example.com/", + search = "", + hash = "", + }, + { + input = "javascript:/example.com/", + base = "http://example.org/foo/bar", + href = "javascript:/example.com/", + origin = "null", + protocol = "javascript:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/example.com/", + search = "", + hash = "", + }, + { + input = "mailto:/example.com/", + base = "http://example.org/foo/bar", + href = "mailto:/example.com/", + origin = "null", + protocol = "mailto:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/example.com/", + search = "", + hash = "", + }, + { + input = "http:example.com/", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/example.com/", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/example.com/", + search = "", + hash = "", + }, + { + input = "ftp:example.com/", + base = "http://example.org/foo/bar", + href = "ftp://example.com/", + origin = "ftp://example.com", + protocol = "ftp:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "https:example.com/", + base = "http://example.org/foo/bar", + href = "https://example.com/", + origin = "https://example.com", + protocol = "https:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "madeupscheme:example.com/", + base = "http://example.org/foo/bar", + href = "madeupscheme:example.com/", + origin = "null", + protocol = "madeupscheme:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "example.com/", + search = "", + hash = "", + }, + { + input = "ftps:example.com/", + base = "http://example.org/foo/bar", + href = "ftps:example.com/", + origin = "null", + protocol = "ftps:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "example.com/", + search = "", + hash = "", + }, + { + input = "gopher:example.com/", + base = "http://example.org/foo/bar", + href = "gopher:example.com/", + origin = "null", + protocol = "gopher:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "example.com/", + search = "", + hash = "", + }, + { + input = "ws:example.com/", + base = "http://example.org/foo/bar", + href = "ws://example.com/", + origin = "ws://example.com", + protocol = "ws:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "wss:example.com/", + base = "http://example.org/foo/bar", + href = "wss://example.com/", + origin = "wss://example.com", + protocol = "wss:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "data:example.com/", + base = "http://example.org/foo/bar", + href = "data:example.com/", + origin = "null", + protocol = "data:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "example.com/", + search = "", + hash = "", + }, + { + input = "javascript:example.com/", + base = "http://example.org/foo/bar", + href = "javascript:example.com/", + origin = "null", + protocol = "javascript:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "example.com/", + search = "", + hash = "", + }, + { + input = "mailto:example.com/", + base = "http://example.org/foo/bar", + href = "mailto:example.com/", + origin = "null", + protocol = "mailto:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "example.com/", + search = "", + hash = "", + }, + { + input = "/a/b/c", + base = "http://example.org/foo/bar", + href = "http://example.org/a/b/c", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/a/b/c", + search = "", + hash = "", + }, + { + input = "/a/ /c", + base = "http://example.org/foo/bar", + href = "http://example.org/a/%2520/c", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/a/%2520/c", + search = "", + hash = "", + }, + { + input = "/a%252fc", + base = "http://example.org/foo/bar", + href = "http://example.org/a%252fc", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/a%252fc", + search = "", + hash = "", + }, + { + input = "/a/%252f/c", + base = "http://example.org/foo/bar", + href = "http://example.org/a/%252f/c", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/a/%252f/c", + search = "", + hash = "", + }, + { + input = "#%CE%B2", + base = "http://example.org/foo/bar", + href = "http://example.org/foo/bar#%25CE%25B2", + origin = "http://example.org", + protocol = "http:", + username = "", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/foo/bar", + search = "", + hash = "#%25CE%25B2", + }, + { + input = "data:text/html,test#test", + base = "http://example.org/foo/bar", + href = "data:text/html,test#test", + origin = "null", + protocol = "data:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "text/html,test", + search = "", + hash = "#test", + }, + { + input = "tel:1234567890", + base = "http://example.org/foo/bar", + href = "tel:1234567890", + origin = "null", + protocol = "tel:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "1234567890", + search = "", + hash = "", + }, + "# Based on https://felixfbecker.github.io/whatwg-url-custom-host-repro/", + { + input = "ssh://example.com/foo/bar.git", + base = "http://example.org/", + href = "ssh://example.com/foo/bar.git", + origin = "null", + protocol = "ssh:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo/bar.git", + search = "", + hash = "", + }, + "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/file.html", + { + input = "file:c:%5Cfoo%5Cbar.html", + base = "file:///tmp/mock/path", + href = "file:///c:/foo/bar.html", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/c:/foo/bar.html", + search = "", + hash = "", + }, + { + input = " File:c|////foo%5Cbar.html", + base = "file:///tmp/mock/path", + href = "file:///c:////foo/bar.html", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/c:////foo/bar.html", + search = "", + hash = "", + }, + { + input = "C|/foo/bar", + base = "file:///tmp/mock/path", + href = "file:///C:/foo/bar", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/C:/foo/bar", + search = "", + hash = "", + }, + { + input = "/C|%5Cfoo%5Cbar", + base = "file:///tmp/mock/path", + href = "file:///C:/foo/bar", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/C:/foo/bar", + search = "", + hash = "", + }, + { + input = "//C|/foo/bar", + base = "file:///tmp/mock/path", + href = "file:///C:/foo/bar", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/C:/foo/bar", + search = "", + hash = "", + }, + { + input = "//server/file", + base = "file:///tmp/mock/path", + href = "file://server/file", + protocol = "file:", + username = "", + password = "", + host = "server", + hostname = "server", + port = "", + pathname = "/file", + search = "", + hash = "", + }, + { + input = "%5C%5Cserver%5Cfile", + base = "file:///tmp/mock/path", + href = "file://server/file", + protocol = "file:", + username = "", + password = "", + host = "server", + hostname = "server", + port = "", + pathname = "/file", + search = "", + hash = "", + }, + { + input = "/%5Cserver/file", + base = "file:///tmp/mock/path", + href = "file://server/file", + protocol = "file:", + username = "", + password = "", + host = "server", + hostname = "server", + port = "", + pathname = "/file", + search = "", + hash = "", + }, + { + input = "file:///foo/bar.txt", + base = "file:///tmp/mock/path", + href = "file:///foo/bar.txt", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/foo/bar.txt", + search = "", + hash = "", + }, + { + input = "file:///home/me", + base = "file:///tmp/mock/path", + href = "file:///home/me", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/home/me", + search = "", + hash = "", + }, + { + input = "//", + base = "file:///tmp/mock/path", + href = "file:///", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "///", + base = "file:///tmp/mock/path", + href = "file:///", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "///test", + base = "file:///tmp/mock/path", + href = "file:///test", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/test", + search = "", + hash = "", + }, + { + input = "file://test", + base = "file:///tmp/mock/path", + href = "file://test/", + protocol = "file:", + username = "", + password = "", + host = "test", + hostname = "test", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "file://localhost", + base = "file:///tmp/mock/path", + href = "file:///", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "file://localhost/", + base = "file:///tmp/mock/path", + href = "file:///", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "file://localhost/test", + base = "file:///tmp/mock/path", + href = "file:///test", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/test", + search = "", + hash = "", + }, + { + input = "test", + base = "file:///tmp/mock/path", + href = "file:///tmp/mock/test", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/tmp/mock/test", + search = "", + hash = "", + }, + { + input = "file:test", + base = "file:///tmp/mock/path", + href = "file:///tmp/mock/test", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/tmp/mock/test", + search = "", + hash = "", + }, + { + input = "file:///w|m", + base = nil, + href = "file:///w|m", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/w|m", + search = "", + hash = "", + }, + { + input = "file:///w||m", + base = nil, + href = "file:///w||m", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/w||m", + search = "", + hash = "", + }, + { + input = "file:///w|/m", + base = nil, + href = "file:///w:/m", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/w:/m", + search = "", + hash = "", + }, + { + input = "file:C|/m/", + base = nil, + href = "file:///C:/m/", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/C:/m/", + search = "", + hash = "", + }, + { + input = "file:C||/m/", + base = nil, + href = "file:///C||/m/", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/C||/m/", + search = "", + hash = "", + }, + "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/script-tests/path.js", + { + input = "http://example.com/././foo", + base = nil, + href = "http://example.com/foo", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo", + search = "", + hash = "", + }, + { + input = "http://example.com/./.foo", + base = nil, + href = "http://example.com/.foo", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/.foo", + search = "", + hash = "", + }, + { + input = "http://example.com/foo/.", + base = nil, + href = "http://example.com/foo/", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo/", + search = "", + hash = "", + }, + { + input = "http://example.com/foo/./", + base = nil, + href = "http://example.com/foo/", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo/", + search = "", + hash = "", + }, + { + input = "http://example.com/foo/bar/..", + base = nil, + href = "http://example.com/foo/", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo/", + search = "", + hash = "", + }, + { + input = "http://example.com/foo/bar/../", + base = nil, + href = "http://example.com/foo/", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo/", + search = "", + hash = "", + }, + { + input = "http://example.com/foo/..bar", + base = nil, + href = "http://example.com/foo/..bar", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo/..bar", + search = "", + hash = "", + }, + { + input = "http://example.com/foo/bar/../ton", + base = nil, + href = "http://example.com/foo/ton", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo/ton", + search = "", + hash = "", + }, + { + input = "http://example.com/foo/bar/../ton/../../a", + base = nil, + href = "http://example.com/a", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/a", + search = "", + hash = "", + }, + { + input = "http://example.com/foo/../../..", + base = nil, + href = "http://example.com/", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://example.com/foo/../../../ton", + base = nil, + href = "http://example.com/ton", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/ton", + search = "", + hash = "", + }, + { + input = "http://example.com/foo/%252e", + base = nil, + href = "http://example.com/foo/", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo/", + search = "", + hash = "", + }, + { + input = "http://example.com/foo/%252e%252", + base = nil, + href = "http://example.com/foo/%252e%252", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo/%252e%252", + search = "", + hash = "", + }, + { + input = "http://example.com/foo/%252e./%252e%252e/.%252e/%252e.bar", + base = nil, + href = "http://example.com/%252e.bar", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/%252e.bar", + search = "", + hash = "", + }, + { + input = "http://example.com////../..", + base = nil, + href = "http://example.com//", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "//", + search = "", + hash = "", + }, + { + input = "http://example.com/foo/bar//../..", + base = nil, + href = "http://example.com/foo/", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo/", + search = "", + hash = "", + }, + { + input = "http://example.com/foo/bar//..", + base = nil, + href = "http://example.com/foo/bar/", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo/bar/", + search = "", + hash = "", + }, + { + input = "http://example.com/foo", + base = nil, + href = "http://example.com/foo", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo", + search = "", + hash = "", + }, + { + input = "http://example.com/%2520foo", + base = nil, + href = "http://example.com/%2520foo", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/%2520foo", + search = "", + hash = "", + }, + { + input = "http://example.com/foo%25", + base = nil, + href = "http://example.com/foo%25", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo%25", + search = "", + hash = "", + }, + { + input = "http://example.com/foo%252", + base = nil, + href = "http://example.com/foo%252", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo%252", + search = "", + hash = "", + }, + { + input = "http://example.com/foo%252zbar", + base = nil, + href = "http://example.com/foo%252zbar", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo%252zbar", + search = "", + hash = "", + }, + { + input = "http://example.com/foo%252%C3%82%C2%A9zbar", + base = nil, + href = "http://example.com/foo%252%25C3%2582%25C2%25A9zbar", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo%252%25C3%2582%25C2%25A9zbar", + search = "", + hash = "", + }, + { + input = "http://example.com/foo%2541%257a", + base = nil, + href = "http://example.com/foo%2541%257a", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo%2541%257a", + search = "", + hash = "", + }, + { + input = "http://example.com/foo%09%C2%91%2591", + base = nil, + href = "http://example.com/foo%25C2%2591%2591", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo%25C2%2591%2591", + search = "", + hash = "", + }, + { + input = "http://example.com/foo%2500%2551", + base = nil, + href = "http://example.com/foo%2500%2551", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foo%2500%2551", + search = "", + hash = "", + }, + { + input = "http://example.com/(%2528:%253A%2529)", + base = nil, + href = "http://example.com/(%2528:%253A%2529)", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/(%2528:%253A%2529)", + search = "", + hash = "", + }, + { + input = "http://example.com/%253A%253a%253C%253c", + base = nil, + href = "http://example.com/%253A%253a%253C%253c", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/%253A%253a%253C%253c", + search = "", + hash = "", + }, + { + input = "http://example.com/foo%09bar", + base = nil, + href = "http://example.com/foobar", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/foobar", + search = "", + hash = "", + }, + { + input = "http://example.com%5C%5Cfoo%5C%5Cbar", + base = nil, + href = "http://example.com//foo//bar", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "//foo//bar", + search = "", + hash = "", + }, + { + input = "http://example.com/%257Ffp3%253Eju%253Dduvgw%253Dd", + base = nil, + href = "http://example.com/%257Ffp3%253Eju%253Dduvgw%253Dd", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/%257Ffp3%253Eju%253Dduvgw%253Dd", + search = "", + hash = "", + }, + { + input = "http://example.com/@asdf%2540", + base = nil, + href = "http://example.com/@asdf%2540", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/@asdf%2540", + search = "", + hash = "", + }, + { + input = "http://example.com/%E4%BD%A0%E5%A5%BD%E4%BD%A0%E5%A5%BD", + base = nil, + href = "http://example.com/%25E4%25BD%25A0%25E5%25A5%25BD%25E4%25BD%25A0%25E5%25A5%25BD", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/%25E4%25BD%25A0%25E5%25A5%25BD%25E4%25BD%25A0%25E5%25A5%25BD", + search = "", + hash = "", + }, + { + input = "http://example.com/%E2%80%A5/foo", + base = nil, + href = "http://example.com/%25E2%2580%25A5/foo", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/%25E2%2580%25A5/foo", + search = "", + hash = "", + }, + { + input = "http://example.com/%EF%BB%BF/foo", + base = nil, + href = "http://example.com/%25EF%25BB%25BF/foo", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/%25EF%25BB%25BF/foo", + search = "", + hash = "", + }, + { + input = "http://example.com/%E2%80%AE/foo/%E2%80%AD/bar", + base = nil, + href = "http://example.com/%25E2%2580%25AE/foo/%25E2%2580%25AD/bar", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/%25E2%2580%25AE/foo/%25E2%2580%25AD/bar", + search = "", + hash = "", + }, + "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/script-tests/relative.js", + { + input = "http://www.google.com/foo?bar=baz#", + base = nil, + href = "http://www.google.com/foo?bar=baz#", + origin = "http://www.google.com", + protocol = "http:", + username = "", + password = "", + host = "www.google.com", + hostname = "www.google.com", + port = "", + pathname = "/foo", + search = "?bar=baz", + hash = "", + }, + { + input = "http://www.google.com/foo?bar=baz# %C2%BB", + base = nil, + href = "http://www.google.com/foo?bar=baz#%2520%25C2%25BB", + origin = "http://www.google.com", + protocol = "http:", + username = "", + password = "", + host = "www.google.com", + hostname = "www.google.com", + port = "", + pathname = "/foo", + search = "?bar=baz", + hash = "#%2520%25C2%25BB", + }, + { + input = "data:test# %C2%BB", + base = nil, + href = "data:test#%2520%25C2%25BB", + origin = "null", + protocol = "data:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "test", + search = "", + hash = "#%2520%25C2%25BB", + }, + { + input = "http://www.google.com", + base = nil, + href = "http://www.google.com/", + origin = "http://www.google.com", + protocol = "http:", + username = "", + password = "", + host = "www.google.com", + hostname = "www.google.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://192.0x00A80001", + base = nil, + href = "http://192.168.0.1/", + origin = "http://192.168.0.1", + protocol = "http:", + username = "", + password = "", + host = "192.168.0.1", + hostname = "192.168.0.1", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://www/foo%252Ehtml", + base = nil, + href = "http://www/foo%252Ehtml", + origin = "http://www", + protocol = "http:", + username = "", + password = "", + host = "www", + hostname = "www", + port = "", + pathname = "/foo%252Ehtml", + search = "", + hash = "", + }, + { + input = "http://www/foo/%252E/html", + base = nil, + href = "http://www/foo/html", + origin = "http://www", + protocol = "http:", + username = "", + password = "", + host = "www", + hostname = "www", + port = "", + pathname = "/foo/html", + search = "", + hash = "", + }, + { + input = "http://user:pass@/", + base = nil, + failure = true, + }, + { + input = "http://%2525DOMAIN:foobar@foodomain.com/", + base = nil, + href = "http://%2525DOMAIN:foobar@foodomain.com/", + origin = "http://foodomain.com", + protocol = "http:", + username = "%2525DOMAIN", + password = "foobar", + host = "foodomain.com", + hostname = "foodomain.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http:%5C%5Cwww.google.com%5Cfoo", + base = nil, + href = "http://www.google.com/foo", + origin = "http://www.google.com", + protocol = "http:", + username = "", + password = "", + host = "www.google.com", + hostname = "www.google.com", + port = "", + pathname = "/foo", + search = "", + hash = "", + }, + { + input = "http://foo:80/", + base = nil, + href = "http://foo/", + origin = "http://foo", + protocol = "http:", + username = "", + password = "", + host = "foo", + hostname = "foo", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://foo:81/", + base = nil, + href = "http://foo:81/", + origin = "http://foo:81", + protocol = "http:", + username = "", + password = "", + host = "foo:81", + hostname = "foo", + port = "81", + pathname = "/", + search = "", + hash = "", + }, + { + input = "httpa://foo:80/", + base = nil, + href = "httpa://foo:80/", + origin = "null", + protocol = "httpa:", + username = "", + password = "", + host = "foo:80", + hostname = "foo", + port = "80", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://foo:-80/", + base = nil, + failure = true, + }, + { + input = "https://foo:443/", + base = nil, + href = "https://foo/", + origin = "https://foo", + protocol = "https:", + username = "", + password = "", + host = "foo", + hostname = "foo", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "https://foo:80/", + base = nil, + href = "https://foo:80/", + origin = "https://foo:80", + protocol = "https:", + username = "", + password = "", + host = "foo:80", + hostname = "foo", + port = "80", + pathname = "/", + search = "", + hash = "", + }, + { + input = "ftp://foo:21/", + base = nil, + href = "ftp://foo/", + origin = "ftp://foo", + protocol = "ftp:", + username = "", + password = "", + host = "foo", + hostname = "foo", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "ftp://foo:80/", + base = nil, + href = "ftp://foo:80/", + origin = "ftp://foo:80", + protocol = "ftp:", + username = "", + password = "", + host = "foo:80", + hostname = "foo", + port = "80", + pathname = "/", + search = "", + hash = "", + }, + { + input = "gopher://foo:70/", + base = nil, + href = "gopher://foo:70/", + origin = "null", + protocol = "gopher:", + username = "", + password = "", + host = "foo:70", + hostname = "foo", + port = "70", + pathname = "/", + search = "", + hash = "", + }, + { + input = "gopher://foo:443/", + base = nil, + href = "gopher://foo:443/", + origin = "null", + protocol = "gopher:", + username = "", + password = "", + host = "foo:443", + hostname = "foo", + port = "443", + pathname = "/", + search = "", + hash = "", + }, + { + input = "ws://foo:80/", + base = nil, + href = "ws://foo/", + origin = "ws://foo", + protocol = "ws:", + username = "", + password = "", + host = "foo", + hostname = "foo", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "ws://foo:81/", + base = nil, + href = "ws://foo:81/", + origin = "ws://foo:81", + protocol = "ws:", + username = "", + password = "", + host = "foo:81", + hostname = "foo", + port = "81", + pathname = "/", + search = "", + hash = "", + }, + { + input = "ws://foo:443/", + base = nil, + href = "ws://foo:443/", + origin = "ws://foo:443", + protocol = "ws:", + username = "", + password = "", + host = "foo:443", + hostname = "foo", + port = "443", + pathname = "/", + search = "", + hash = "", + }, + { + input = "ws://foo:815/", + base = nil, + href = "ws://foo:815/", + origin = "ws://foo:815", + protocol = "ws:", + username = "", + password = "", + host = "foo:815", + hostname = "foo", + port = "815", + pathname = "/", + search = "", + hash = "", + }, + { + input = "wss://foo:80/", + base = nil, + href = "wss://foo:80/", + origin = "wss://foo:80", + protocol = "wss:", + username = "", + password = "", + host = "foo:80", + hostname = "foo", + port = "80", + pathname = "/", + search = "", + hash = "", + }, + { + input = "wss://foo:81/", + base = nil, + href = "wss://foo:81/", + origin = "wss://foo:81", + protocol = "wss:", + username = "", + password = "", + host = "foo:81", + hostname = "foo", + port = "81", + pathname = "/", + search = "", + hash = "", + }, + { + input = "wss://foo:443/", + base = nil, + href = "wss://foo/", + origin = "wss://foo", + protocol = "wss:", + username = "", + password = "", + host = "foo", + hostname = "foo", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "wss://foo:815/", + base = nil, + href = "wss://foo:815/", + origin = "wss://foo:815", + protocol = "wss:", + username = "", + password = "", + host = "foo:815", + hostname = "foo", + port = "815", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http:/example.com/", + base = nil, + href = "http://example.com/", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "ftp:/example.com/", + base = nil, + href = "ftp://example.com/", + origin = "ftp://example.com", + protocol = "ftp:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "https:/example.com/", + base = nil, + href = "https://example.com/", + origin = "https://example.com", + protocol = "https:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "madeupscheme:/example.com/", + base = nil, + href = "madeupscheme:/example.com/", + origin = "null", + protocol = "madeupscheme:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/example.com/", + search = "", + hash = "", + }, + { + input = "file:/example.com/", + base = nil, + href = "file:///example.com/", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/example.com/", + search = "", + hash = "", + }, + { + input = "ftps:/example.com/", + base = nil, + href = "ftps:/example.com/", + origin = "null", + protocol = "ftps:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/example.com/", + search = "", + hash = "", + }, + { + input = "gopher:/example.com/", + base = nil, + href = "gopher:/example.com/", + origin = "null", + protocol = "gopher:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/example.com/", + search = "", + hash = "", + }, + { + input = "ws:/example.com/", + base = nil, + href = "ws://example.com/", + origin = "ws://example.com", + protocol = "ws:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "wss:/example.com/", + base = nil, + href = "wss://example.com/", + origin = "wss://example.com", + protocol = "wss:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "data:/example.com/", + base = nil, + href = "data:/example.com/", + origin = "null", + protocol = "data:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/example.com/", + search = "", + hash = "", + }, + { + input = "javascript:/example.com/", + base = nil, + href = "javascript:/example.com/", + origin = "null", + protocol = "javascript:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/example.com/", + search = "", + hash = "", + }, + { + input = "mailto:/example.com/", + base = nil, + href = "mailto:/example.com/", + origin = "null", + protocol = "mailto:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/example.com/", + search = "", + hash = "", + }, + { + input = "http:example.com/", + base = nil, + href = "http://example.com/", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "ftp:example.com/", + base = nil, + href = "ftp://example.com/", + origin = "ftp://example.com", + protocol = "ftp:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "https:example.com/", + base = nil, + href = "https://example.com/", + origin = "https://example.com", + protocol = "https:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "madeupscheme:example.com/", + base = nil, + href = "madeupscheme:example.com/", + origin = "null", + protocol = "madeupscheme:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "example.com/", + search = "", + hash = "", + }, + { + input = "ftps:example.com/", + base = nil, + href = "ftps:example.com/", + origin = "null", + protocol = "ftps:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "example.com/", + search = "", + hash = "", + }, + { + input = "gopher:example.com/", + base = nil, + href = "gopher:example.com/", + origin = "null", + protocol = "gopher:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "example.com/", + search = "", + hash = "", + }, + { + input = "ws:example.com/", + base = nil, + href = "ws://example.com/", + origin = "ws://example.com", + protocol = "ws:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "wss:example.com/", + base = nil, + href = "wss://example.com/", + origin = "wss://example.com", + protocol = "wss:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "data:example.com/", + base = nil, + href = "data:example.com/", + origin = "null", + protocol = "data:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "example.com/", + search = "", + hash = "", + }, + { + input = "javascript:example.com/", + base = nil, + href = "javascript:example.com/", + origin = "null", + protocol = "javascript:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "example.com/", + search = "", + hash = "", + }, + { + input = "mailto:example.com/", + base = nil, + href = "mailto:example.com/", + origin = "null", + protocol = "mailto:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "example.com/", + search = "", + hash = "", + }, + "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/segments-userinfo-vs-host.html", + { + input = "http:@www.example.com", + base = nil, + href = "http://www.example.com/", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http:/@www.example.com", + base = nil, + href = "http://www.example.com/", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://@www.example.com", + base = nil, + href = "http://www.example.com/", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http:a:b@www.example.com", + base = nil, + href = "http://a:b@www.example.com/", + origin = "http://www.example.com", + protocol = "http:", + username = "a", + password = "b", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http:/a:b@www.example.com", + base = nil, + href = "http://a:b@www.example.com/", + origin = "http://www.example.com", + protocol = "http:", + username = "a", + password = "b", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://a:b@www.example.com", + base = nil, + href = "http://a:b@www.example.com/", + origin = "http://www.example.com", + protocol = "http:", + username = "a", + password = "b", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://@pple.com", + base = nil, + href = "http://pple.com/", + origin = "http://pple.com", + protocol = "http:", + username = "", + password = "", + host = "pple.com", + hostname = "pple.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http::b@www.example.com", + base = nil, + href = "http://:b@www.example.com/", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "b", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http:/:b@www.example.com", + base = nil, + href = "http://:b@www.example.com/", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "b", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://:b@www.example.com", + base = nil, + href = "http://:b@www.example.com/", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "b", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http:/:@/www.example.com", + base = nil, + failure = true, + relativeTo = "non-opaque-path-base", + }, + { + input = "http://user@/www.example.com", + base = nil, + failure = true, + }, + { + input = "http:@/www.example.com", + base = nil, + failure = true, + relativeTo = "non-opaque-path-base", + }, + { + input = "http:/@/www.example.com", + base = nil, + failure = true, + relativeTo = "non-opaque-path-base", + }, + { + input = "http://@/www.example.com", + base = nil, + failure = true, + }, + { + input = "https:@/www.example.com", + base = nil, + failure = true, + relativeTo = "non-opaque-path-base", + }, + { + input = "http:a:b@/www.example.com", + base = nil, + failure = true, + relativeTo = "non-opaque-path-base", + }, + { + input = "http:/a:b@/www.example.com", + base = nil, + failure = true, + relativeTo = "non-opaque-path-base", + }, + { + input = "http://a:b@/www.example.com", + base = nil, + failure = true, + }, + { + input = "http::@/www.example.com", + base = nil, + failure = true, + relativeTo = "non-opaque-path-base", + }, + { + input = "http:a:@www.example.com", + base = nil, + href = "http://a@www.example.com/", + origin = "http://www.example.com", + protocol = "http:", + username = "a", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http:/a:@www.example.com", + base = nil, + href = "http://a@www.example.com/", + origin = "http://www.example.com", + protocol = "http:", + username = "a", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://a:@www.example.com", + base = nil, + href = "http://a@www.example.com/", + origin = "http://www.example.com", + protocol = "http:", + username = "a", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://www.@pple.com", + base = nil, + href = "http://www.@pple.com/", + origin = "http://pple.com", + protocol = "http:", + username = "www.", + password = "", + host = "pple.com", + hostname = "pple.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http:@:www.example.com", + base = nil, + failure = true, + relativeTo = "non-opaque-path-base", + }, + { + input = "http:/@:www.example.com", + base = nil, + failure = true, + relativeTo = "non-opaque-path-base", + }, + { + input = "http://@:www.example.com", + base = nil, + failure = true, + }, + { + input = "http://:@www.example.com", + base = nil, + href = "http://www.example.com/", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + "# Others", + { + input = "/", + base = "http://www.example.com/test", + href = "http://www.example.com/", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "/test.txt", + base = "http://www.example.com/test", + href = "http://www.example.com/test.txt", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/test.txt", + search = "", + hash = "", + }, + { + input = ".", + base = "http://www.example.com/test", + href = "http://www.example.com/", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "..", + base = "http://www.example.com/test", + href = "http://www.example.com/", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "test.txt", + base = "http://www.example.com/test", + href = "http://www.example.com/test.txt", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/test.txt", + search = "", + hash = "", + }, + { + input = "./test.txt", + base = "http://www.example.com/test", + href = "http://www.example.com/test.txt", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/test.txt", + search = "", + hash = "", + }, + { + input = "../test.txt", + base = "http://www.example.com/test", + href = "http://www.example.com/test.txt", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/test.txt", + search = "", + hash = "", + }, + { + input = "../aaa/test.txt", + base = "http://www.example.com/test", + href = "http://www.example.com/aaa/test.txt", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/aaa/test.txt", + search = "", + hash = "", + }, + { + input = "../../test.txt", + base = "http://www.example.com/test", + href = "http://www.example.com/test.txt", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/test.txt", + search = "", + hash = "", + }, + { + input = "%E4%B8%AD/test.txt", + base = "http://www.example.com/test", + href = "http://www.example.com/%25E4%25B8%25AD/test.txt", + origin = "http://www.example.com", + protocol = "http:", + username = "", + password = "", + host = "www.example.com", + hostname = "www.example.com", + port = "", + pathname = "/%25E4%25B8%25AD/test.txt", + search = "", + hash = "", + }, + { + input = "http://www.example2.com", + base = "http://www.example.com/test", + href = "http://www.example2.com/", + origin = "http://www.example2.com", + protocol = "http:", + username = "", + password = "", + host = "www.example2.com", + hostname = "www.example2.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "//www.example2.com", + base = "http://www.example.com/test", + href = "http://www.example2.com/", + origin = "http://www.example2.com", + protocol = "http:", + username = "", + password = "", + host = "www.example2.com", + hostname = "www.example2.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "file:...", + base = "http://www.example.com/test", + href = "file:///...", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/...", + search = "", + hash = "", + }, + { + input = "file:..", + base = "http://www.example.com/test", + href = "file:///", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "file:a", + base = "http://www.example.com/test", + href = "file:///a", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/a", + search = "", + hash = "", + }, + { + input = "file:.", + base = nil, + href = "file:///", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "file:.", + base = "http://www.example.com/test", + href = "file:///", + protocol = "file:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/", + search = "", + hash = "", + }, + "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/host.html", + "Basic canonicalization, uppercase should be converted to lowercase", + { + input = "http://ExAmPlE.CoM", + base = "http://other.com/", + href = "http://example.com/", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://example example.com", + base = "http://other.com/", + failure = true, + }, + { + input = "http://Goo%2520 goo%257C|.com", + base = "http://other.com/", + failure = true, + }, + { + input = "http://[]", + base = "http://other.com/", + failure = true, + }, + { + input = "http://[:]", + base = "http://other.com/", + failure = true, + }, + "U+3000 is mapped to U+0020 (space) which is disallowed", + { + input = "http://GOO%C2%A0%E3%80%80goo.com", + base = "http://other.com/", + failure = true, + }, + "Other types of space (no-break, zero-width, zero-width-no-break) are name-prepped away to nothing. U+200B, U+2060, and U+FEFF, are ignored", + { + input = "http://GOO%E2%80%8B%E2%81%A0%EF%BB%BFgoo.com", + base = "http://other.com/", + href = "http://googoo.com/", + origin = "http://googoo.com", + protocol = "http:", + username = "", + password = "", + host = "googoo.com", + hostname = "googoo.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + "Leading and trailing C0 control or space", + { + input = "%00%1B%04%12 http://example.com/%1F %0D ", + base = nil, + href = "http://example.com/", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + "Ideographic full stop (full-width period for Chinese, etc.) should be treated as a dot. U+3002 is mapped to U+002E (dot)", + { + input = "http://www.foo%E3%80%82bar.com", + base = "http://other.com/", + href = "http://www.foo.bar.com/", + origin = "http://www.foo.bar.com", + protocol = "http:", + username = "", + password = "", + host = "www.foo.bar.com", + hostname = "www.foo.bar.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + "Invalid unicode characters should fail... U+FDD0 is disallowed; %ef%b7%90 is U+FDD0", + { + input = "http://%EF%B7%90zyx.com", + base = "http://other.com/", + failure = true, + }, + "This is the same as previous but escaped", + { + input = "http://%25ef%25b7%2590zyx.com", + base = "http://other.com/", + failure = true, + }, + "U+FFFD", + { + input = "https://%EF%BF%BD", + base = nil, + failure = true, + }, + { + input = "https://%25EF%25BF%25BD", + base = nil, + failure = true, + }, + { + input = "https://x/%EF%BF%BD?%EF%BF%BD#%EF%BF%BD", + base = nil, + href = "https://x/%25EF%25BF%25BD?%25EF%25BF%25BD#%25EF%25BF%25BD", + origin = "https://x", + protocol = "https:", + username = "", + password = "", + host = "x", + hostname = "x", + port = "", + pathname = "/%25EF%25BF%25BD", + search = "?%25EF%25BF%25BD", + hash = "#%25EF%25BF%25BD", + }, + "Domain is ASCII, but a label is invalid IDNA", + { + input = "http://a.b.c.xn--pokxncvks", + base = nil, + failure = true, + }, + { + input = "http://10.0.0.xn--pokxncvks", + base = nil, + failure = true, + }, + "IDNA labels should be matched case-insensitively", + { + input = "http://a.b.c.XN--pokxncvks", + base = nil, + failure = true, + }, + { + input = "http://a.b.c.Xn--pokxncvks", + base = nil, + failure = true, + }, + { + input = "http://10.0.0.XN--pokxncvks", + base = nil, + failure = true, + }, + { + input = "http://10.0.0.xN--pokxncvks", + base = nil, + failure = true, + }, + "Test name prepping, fullwidth input should be converted to ASCII and NOT IDN-ized. This is 'Go' in fullwidth UTF-8/UTF-16.", + { + input = "http://%EF%BC%A7%EF%BD%8F.com", + base = "http://other.com/", + href = "http://go.com/", + origin = "http://go.com", + protocol = "http:", + username = "", + password = "", + host = "go.com", + hostname = "go.com", + port = "", + pathname = "/", + search = "", + hash = "", + }, + "URL spec forbids the following. https://www.w3.org/Bugs/Public/show_bug.cgi?id=24257", + { + input = "http://%EF%BC%85%EF%BC%94%EF%BC%91.com", + base = "http://other.com/", + failure = true, + }, + { + input = "http://%25ef%25bc%2585%25ef%25bc%2594%25ef%25bc%2591.com", + base = "http://other.com/", + failure = true, + }, + "...%00 in fullwidth should fail (also as escaped UTF-8 input)", + { + input = "http://%EF%BC%85%EF%BC%90%EF%BC%90.com", + base = "http://other.com/", + failure = true, + }, + { + input = "http://%25ef%25bc%2585%25ef%25bc%2590%25ef%25bc%2590.com", + base = "http://other.com/", + failure = true, + }, + "Basic IDN support, UTF-8 and UTF-16 input should be converted to IDN", + { + input = "http://%E4%BD%A0%E5%A5%BD%E4%BD%A0%E5%A5%BD", + base = "http://other.com/", + href = "http://xn--6qqa088eba/", + origin = "http://xn--6qqa088eba", + protocol = "http:", + username = "", + password = "", + host = "xn--6qqa088eba", + hostname = "xn--6qqa088eba", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "https://fa%C3%9F.ExAmPlE/", + base = nil, + href = "https://xn--fa-hia.example/", + origin = "https://xn--fa-hia.example", + protocol = "https:", + username = "", + password = "", + host = "xn--fa-hia.example", + hostname = "xn--fa-hia.example", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "sc://fa%C3%9F.ExAmPlE/", + base = nil, + href = "sc://fa%25C3%259F.ExAmPlE/", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "fa%25C3%259F.ExAmPlE", + hostname = "fa%25C3%259F.ExAmPlE", + port = "", + pathname = "/", + search = "", + hash = "", + }, + "Invalid escaped characters should fail and the percents should be escaped. https://www.w3.org/Bugs/Public/show_bug.cgi?id=24191", + { + input = "http://%25zz%2566%25a.com", + base = "http://other.com/", + failure = true, + }, + "If we get an invalid character that has been escaped.", + { + input = "http://%2525", + base = "http://other.com/", + failure = true, + }, + { + input = "http://hello%2500", + base = "http://other.com/", + failure = true, + }, + "Escaped numbers should be treated like IP addresses if they are.", + { + input = "http://%2530%2578%2563%2530%252e%2530%2532%2535%2530.01", + base = "http://other.com/", + href = "http://192.168.0.1/", + origin = "http://192.168.0.1", + protocol = "http:", + username = "", + password = "", + host = "192.168.0.1", + hostname = "192.168.0.1", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://%2530%2578%2563%2530%252e%2530%2532%2535%2530.01%252e", + base = "http://other.com/", + href = "http://192.168.0.1/", + origin = "http://192.168.0.1", + protocol = "http:", + username = "", + password = "", + host = "192.168.0.1", + hostname = "192.168.0.1", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://192.168.0.257", + base = "http://other.com/", + failure = true, + }, + "Invalid escaping in hosts causes failure", + { + input = "http://%253g%2578%2563%2530%252e%2530%2532%2535%2530%252E.01", + base = "http://other.com/", + failure = true, + }, + "A space in a host causes failure", + { + input = "http://192.168.0.1 hello", + base = "http://other.com/", + failure = true, + }, + { + input = "https://x x:12", + base = nil, + failure = true, + }, + "Fullwidth and escaped UTF-8 fullwidth should still be treated as IP", + { + input = "http://%EF%BC%90%EF%BC%B8%EF%BD%83%EF%BC%90%EF%BC%8E%EF%BC%90%EF%BC%92%EF%BC%95%EF%BC%90%EF%BC%8E%EF%BC%90%EF%BC%91", + base = "http://other.com/", + href = "http://192.168.0.1/", + origin = "http://192.168.0.1", + protocol = "http:", + username = "", + password = "", + host = "192.168.0.1", + hostname = "192.168.0.1", + port = "", + pathname = "/", + search = "", + hash = "", + }, + "Domains with empty labels", + { + input = "http://./", + base = nil, + href = "http://./", + origin = "http://.", + protocol = "http:", + username = "", + password = "", + host = ".", + hostname = ".", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "http://../", + base = nil, + href = "http://../", + origin = "http://..", + protocol = "http:", + username = "", + password = "", + host = "..", + hostname = "..", + port = "", + pathname = "/", + search = "", + hash = "", + }, + "Non-special domains with empty labels", + { + input = "h://.", + base = nil, + href = "h://.", + origin = "null", + protocol = "h:", + username = "", + password = "", + host = ".", + hostname = ".", + port = "", + pathname = "", + search = "", + hash = "", + }, + "Broken IPv6", + { + input = "http://[www.google.com]/", + base = nil, + failure = true, + }, + { + input = "http://[google.com]", + base = "http://other.com/", + failure = true, + }, + { + input = "http://[::1.2.3.4x]", + base = "http://other.com/", + failure = true, + }, + { + input = "http://[::1.2.3.]", + base = "http://other.com/", + failure = true, + }, + { + input = "http://[::1.2.]", + base = "http://other.com/", + failure = true, + }, + { + input = "http://[::.1.2]", + base = "http://other.com/", + failure = true, + }, + { + input = "http://[::1.]", + base = "http://other.com/", + failure = true, + }, + { + input = "http://[::.1]", + base = "http://other.com/", + failure = true, + }, + { + input = "http://[::%2531]", + base = "http://other.com/", + failure = true, + }, + { + input = "http://%255B::1]", + base = "http://other.com/", + failure = true, + }, + "Misc Unicode", + { + input = "http://foo:%F0%9F%92%A9@example.com/bar", + base = "http://other.com/", + href = "http://foo:%25F0%259F%2592%25A9@example.com/bar", + origin = "http://example.com", + protocol = "http:", + username = "foo", + password = "%25F0%259F%2592%25A9", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/bar", + search = "", + hash = "", + }, + "# resolving a fragment against any scheme succeeds", + { + input = "#", + base = "test:test", + href = "test:test#", + origin = "null", + protocol = "test:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "test", + search = "", + hash = "", + }, + { + input = "#x", + base = "mailto:x@x.com", + href = "mailto:x@x.com#x", + origin = "null", + protocol = "mailto:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "x@x.com", + search = "", + hash = "#x", + }, + { + input = "#x", + base = "data:,", + href = "data:,#x", + origin = "null", + protocol = "data:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = ",", + search = "", + hash = "#x", + }, + { + input = "#x", + base = "about:blank", + href = "about:blank#x", + origin = "null", + protocol = "about:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "blank", + search = "", + hash = "#x", + }, + { + input = "#x:y", + base = "about:blank", + href = "about:blank#x:y", + origin = "null", + protocol = "about:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "blank", + search = "", + hash = "#x:y", + }, + { + input = "#", + base = "test:test?test", + href = "test:test?test#", + origin = "null", + protocol = "test:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "test", + search = "?test", + hash = "", + }, + "# multiple @ in authority state", + { + input = "https://@test@test@example:800/", + base = "http://doesnotmatter/", + href = "https://%2540test%2540test@example:800/", + origin = "https://example:800", + protocol = "https:", + username = "%2540test%2540test", + password = "", + host = "example:800", + hostname = "example", + port = "800", + pathname = "/", + search = "", + hash = "", + }, + { + input = "https://@@@example", + base = "http://doesnotmatter/", + href = "https://%2540%2540@example/", + origin = "https://example", + protocol = "https:", + username = "%2540%2540", + password = "", + host = "example", + hostname = "example", + port = "", + pathname = "/", + search = "", + hash = "", + }, + "non-az-09 characters", + { + input = "http://`{}:`{}@h/`{}?`{}", + base = "http://doesnotmatter/", + href = "http://%2560%257B%257D:%2560%257B%257D@h/%2560%257B%257D?`{}", + origin = "http://h", + protocol = "http:", + username = "%2560%257B%257D", + password = "%2560%257B%257D", + host = "h", + hostname = "h", + port = "", + pathname = "/%2560%257B%257D", + search = "?`{}", + hash = "", + }, + "byte is ' and url is special", + { + input = "http://host/?'", + base = nil, + href = "http://host/?%2527", + origin = "http://host", + protocol = "http:", + username = "", + password = "", + host = "host", + hostname = "host", + port = "", + pathname = "/", + search = "?%2527", + hash = "", + }, + { + input = "notspecial://host/?'", + base = nil, + href = "notspecial://host/?'", + origin = "null", + protocol = "notspecial:", + username = "", + password = "", + host = "host", + hostname = "host", + port = "", + pathname = "/", + search = "?'", + hash = "", + }, + "# Credentials in base", + { + input = "/some/path", + base = "http://user@example.org/smth", + href = "http://user@example.org/some/path", + origin = "http://example.org", + protocol = "http:", + username = "user", + password = "", + host = "example.org", + hostname = "example.org", + port = "", + pathname = "/some/path", + search = "", + hash = "", + }, + { + input = "", + base = "http://user:pass@example.org:21/smth", + href = "http://user:pass@example.org:21/smth", + origin = "http://example.org:21", + protocol = "http:", + username = "user", + password = "pass", + host = "example.org:21", + hostname = "example.org", + port = "21", + pathname = "/smth", + search = "", + hash = "", + }, + { + input = "/some/path", + base = "http://user:pass@example.org:21/smth", + href = "http://user:pass@example.org:21/some/path", + origin = "http://example.org:21", + protocol = "http:", + username = "user", + password = "pass", + host = "example.org:21", + hostname = "example.org", + port = "21", + pathname = "/some/path", + search = "", + hash = "", + }, + "# a set of tests designed by zcorpan for relative URLs with unknown schemes", + { + input = "i", + base = "sc:sd", + failure = true, + }, + { + input = "i", + base = "sc:sd/sd", + failure = true, + }, + { + input = "i", + base = "sc:/pa/pa", + href = "sc:/pa/i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/pa/i", + search = "", + hash = "", + }, + { + input = "i", + base = "sc://ho/pa", + href = "sc://ho/i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "ho", + hostname = "ho", + port = "", + pathname = "/i", + search = "", + hash = "", + }, + { + input = "i", + base = "sc:///pa/pa", + href = "sc:///pa/i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/pa/i", + search = "", + hash = "", + }, + { + input = "../i", + base = "sc:sd", + failure = true, + }, + { + input = "../i", + base = "sc:sd/sd", + failure = true, + }, + { + input = "../i", + base = "sc:/pa/pa", + href = "sc:/i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/i", + search = "", + hash = "", + }, + { + input = "../i", + base = "sc://ho/pa", + href = "sc://ho/i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "ho", + hostname = "ho", + port = "", + pathname = "/i", + search = "", + hash = "", + }, + { + input = "../i", + base = "sc:///pa/pa", + href = "sc:///i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/i", + search = "", + hash = "", + }, + { + input = "/i", + base = "sc:sd", + failure = true, + }, + { + input = "/i", + base = "sc:sd/sd", + failure = true, + }, + { + input = "/i", + base = "sc:/pa/pa", + href = "sc:/i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/i", + search = "", + hash = "", + }, + { + input = "/i", + base = "sc://ho/pa", + href = "sc://ho/i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "ho", + hostname = "ho", + port = "", + pathname = "/i", + search = "", + hash = "", + }, + { + input = "/i", + base = "sc:///pa/pa", + href = "sc:///i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/i", + search = "", + hash = "", + }, + { + input = "?i", + base = "sc:sd", + failure = true, + }, + { + input = "?i", + base = "sc:sd/sd", + failure = true, + }, + { + input = "?i", + base = "sc:/pa/pa", + href = "sc:/pa/pa?i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/pa/pa", + search = "?i", + hash = "", + }, + { + input = "?i", + base = "sc://ho/pa", + href = "sc://ho/pa?i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "ho", + hostname = "ho", + port = "", + pathname = "/pa", + search = "?i", + hash = "", + }, + { + input = "?i", + base = "sc:///pa/pa", + href = "sc:///pa/pa?i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/pa/pa", + search = "?i", + hash = "", + }, + { + input = "#i", + base = "sc:sd", + href = "sc:sd#i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "sd", + search = "", + hash = "#i", + }, + { + input = "#i", + base = "sc:sd/sd", + href = "sc:sd/sd#i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "sd/sd", + search = "", + hash = "#i", + }, + { + input = "#i", + base = "sc:/pa/pa", + href = "sc:/pa/pa#i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/pa/pa", + search = "", + hash = "#i", + }, + { + input = "#i", + base = "sc://ho/pa", + href = "sc://ho/pa#i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "ho", + hostname = "ho", + port = "", + pathname = "/pa", + search = "", + hash = "#i", + }, + { + input = "#i", + base = "sc:///pa/pa", + href = "sc:///pa/pa#i", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/pa/pa", + search = "", + hash = "#i", + }, + "# make sure that relative URL logic works on known typically non-relative schemes too", + { + input = "about:/../", + base = nil, + href = "about:/", + origin = "null", + protocol = "about:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "data:/../", + base = nil, + href = "data:/", + origin = "null", + protocol = "data:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "javascript:/../", + base = nil, + href = "javascript:/", + origin = "null", + protocol = "javascript:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "mailto:/../", + base = nil, + href = "mailto:/", + origin = "null", + protocol = "mailto:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "/", + search = "", + hash = "", + }, + "# unknown schemes and their hosts", + { + input = "sc://%C3%B1.test/", + base = nil, + href = "sc://%25C3%25B1.test/", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "%25C3%25B1.test", + hostname = "%25C3%25B1.test", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "sc://%25/", + base = nil, + href = "sc://%25/", + protocol = "sc:", + username = "", + password = "", + host = "%25", + hostname = "%25", + port = "", + pathname = "/", + search = "", + hash = "", + }, + { + input = "sc://@/", + base = nil, + failure = true, + }, + { + input = "sc://te@s:t@/", + base = nil, + failure = true, + }, + { + input = "sc://:/", + base = nil, + failure = true, + }, + { + input = "sc://:12/", + base = nil, + failure = true, + }, + { + input = "x", + base = "sc://%C3%B1", + href = "sc://%25C3%25B1/x", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "%25C3%25B1", + hostname = "%25C3%25B1", + port = "", + pathname = "/x", + search = "", + hash = "", + }, + "# unknown schemes and backslashes", + { + input = "sc:%5C../", + base = nil, + href = "sc:%5C../", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "%5C../", + search = "", + hash = "", + }, + "# unknown scheme with path looking like a password", + { + input = "sc::a@example.net", + base = nil, + href = "sc::a@example.net", + origin = "null", + protocol = "sc:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = ":a@example.net", + search = "", + hash = "", + }, + "# unknown scheme with bogus percent-encoding", + { + input = "wow:%25NBD", + base = nil, + href = "wow:%25NBD", + origin = "null", + protocol = "wow:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "%25NBD", + search = "", + hash = "", + }, + { + input = "wow:%251G", + base = nil, + href = "wow:%251G", + origin = "null", + protocol = "wow:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "%251G", + search = "", + hash = "", + }, + "# unknown scheme with non-URL characters", + { + input = "wow:%EF%BF%BF", + base = nil, + href = "wow:%25EF%25BF%25BF", + origin = "null", + protocol = "wow:", + username = "", + password = "", + host = "", + hostname = "", + port = "", + pathname = "%25EF%25BF%25BF", + search = "", + hash = "", + }, + { + input = "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF", + base = nil, + href = "http://example.com/%25EF%25BF%25BD%25F0%2590%259F%25BE%25EF%25BF%25BD%25EF%25B7%2590%25EF%25B7%258F%25EF%25B7%25AF%25EF%25B7%25B0%25EF%25BF%25BE%25EF%25BF%25BF?%25EF%25BF%25BD%25F0%2590%259F%25BE%25EF%25BF%25BD%25EF%25B7%2590%25EF%25B7%258F%25EF%25B7%25AF%25EF%25B7%25B0%25EF%25BF%25BE%25EF%25BF%25BF", + origin = "http://example.com", + protocol = "http:", + username = "", + password = "", + host = "example.com", + hostname = "example.com", + port = "", + pathname = "/%25EF%25BF%25BD%25F0%2590%259F%25BE%25EF%25BF%25BD%25EF%25B7%2590%25EF%25B7%258F%25EF%25B7%25AF%25EF%25B7%25B0%25EF%25BF%25BE%25EF%25BF%25BF", + search = "?%25EF%25BF%25BD%25F0%2590%259F%25BE%25EF%25BF%25BD%25EF%25B7%2590%25EF%25B7%258F%25EF%25B7%25AF%25EF%25B7%25B0%25EF%25BF%25BE%25EF%25BF%25BF", + hash = "", + }, + "Forbidden host code points", + { + input = "sc://a%00b/", + base = nil, + failure = true, + }, + { + input = "sc://a b/", + base = nil, + failure = true, + }, + { + input = "sc://a metatable = getmetatable( any ) return metatable and metatable.__class == URL --- print URL(" \t", "http://example.org/foo/bar").href