1
0

fix url syntax

This commit is contained in:
Arpad Ryszka 2026-06-24 03:28:42 +02:00
parent f2c3942b2c
commit fbb8bcd2c8
2 changed files with 116 additions and 7 deletions

View File

@ -15,7 +15,7 @@ percent-encoded:alias:failpass = "%" hex{2};
path-char:alias:failpass = unreserved | percent-encoded | subdelimiter | ":" | "@";
// scheme:
scheme = alpha (alpha | digit | [+-.])*;
scheme = alpha (alpha | digit | [+\-.])*;
// userinfo:
userinfo = (unreserved | percent-encoded | subdelimiter | ":")*;
@ -30,12 +30,12 @@ ls32:alias:failpass = h16 ":" h16 | ipv4;
ipv6:failpass = (h16 ":"){6} ls32
| "::" (h16 ":"){5} ls32
| h16? "::" (h16 ":"){4} ls32
| ((h16 ":")? h16)? "::" (h16 ":"){3} ls32
| ((h16 ":"){,2} h16)? "::" (h16 ":"){2} ls32
| ((h16 ":"){,3} h16)? "::" h16 ":" ls32
| ((h16 ":"){,4} h16)? "::" ls32
| ((h16 ":"){,5} h16)? "::" h16
| ((h16 ":"){,6} h16)? "::";
| (h16 (":" h16)?)? "::" (h16 ":"){3} ls32
| (h16 (":" h16){,2})? "::" (h16 ":"){2} ls32
| (h16 (":" h16){,3})? "::" h16 ":" ls32
| (h16 (":" h16){,4})? "::" ls32
| (h16 (":" h16){,5})? "::" h16
| (h16 (":" h16){,6})? "::";
zone-id:alias:failpass = (unreserved | percent-encoded)+;
ipv6-zone:failpass = ipv6 "%25" zone-id; // RFC6874

View File

@ -266,6 +266,79 @@ func TestURL(t *testing.T) {
}},
}, {
title: "scheme and host ipv4 as domain name because of numeric range",
input: "http://256.0.0.1",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
expect: "256.0.0.1",
}},
}, {
title: "scheme and host ipv4 as domain name because of leading zero",
input: "http://128.0.0.01",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
expect: "128.0.0.01",
}},
}, {
title: "scheme and host ipv4",
input: "http://128.0.0.1",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname", "ipv4"),
expect: "128.0.0.1",
}},
}, {
title: "scheme and host ipv6",
input: "http://[fe80::1]",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: fakeTRCheck("[fe80::1]"),
expect: "[fe80::1]",
}, {
stdQuery: fakeSTDCheck("fe80::1"),
treerackQuery: queryTreerack("absolute-url", "hostname", "ipv6"),
expect: "fe80::1",
}},
}, {
title: "scheme and host ipv6 with zone",
input: "http://[fe80::1%25eth0]",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: fakeTRCheck("[fe80::1%eth0]"),
expect: "[fe80::1%eth0]",
}, {
stdQuery: fakeSTDCheck("fe80::1%25eth0"),
treerackQuery: queryTreerack("absolute-url", "hostname", "ipv6-zone"),
expect: "fe80::1%25eth0",
}},
}, {
title: "scheme and host with port",
input: "http://foo.bar:8080",
checks: []urlCheck{{
@ -1480,3 +1553,39 @@ func TestURL(t *testing.T) {
})
}
}
func TestURLErrors(t *testing.T) {
for _, test := range []struct{ title, input string }{{
title: "scheme cannot start on a number",
input: "123http://foo.bar/foo/bar",
}, {
title: "scheme characters",
input: "http,unix://foo.bar/foo/bar",
}, {
title: "ipv4 in brackets",
input: "http://[128.0.0.1]",
}, {
title: "ipv6 without closing bracket",
input: "http://[fe80::1%25eth0",
}, {
title: "invalid port",
input: "http://foo.bar:99x99",
}, {
title: "invalid path",
input: "http://foo.bar/foo%xbar",
}} {
t.Run(test.title, func(t *testing.T) {
p := urlParser()
if a, err := p(test.input); err == nil {
printURLTree(t, a)
t.Fatal("failed to fail", test.input)
}
})
}
}