diff options
author | Russ Cox <rsc@golang.org> | 2016-10-20 16:53:49 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2016-10-24 16:04:47 +0000 |
commit | c5ccbdd22bdbdc43d541b7e7d4ed66ceb559030e (patch) | |
tree | b93c3826e9848852f6cb3c8951730787a6876f9c /src/net/url | |
parent | afe675c2fa9deacd61f5684be54f1ebbdc94fc0c (diff) | |
download | go-git-c5ccbdd22bdbdc43d541b7e7d4ed66ceb559030e.tar.gz |
net/url: reject colon in first segment of relative path in Parse
RFC 3986 §3.3 disallows relative URL paths in which the first segment
contains a colon, presumably to avoid confusion with scheme:foo syntax,
which is exactly what happened in #16822.
Fixes #16822.
Change-Id: Ie4449e1dd21c5e56e3b126e086c3a0b05da7ff24
Reviewed-on: https://go-review.googlesource.com/31582
Reviewed-by: Quentin Smith <quentin@golang.org>
Diffstat (limited to 'src/net/url')
-rw-r--r-- | src/net/url/url.go | 13 | ||||
-rw-r--r-- | src/net/url/url_test.go | 8 |
2 files changed, 19 insertions, 2 deletions
diff --git a/src/net/url/url.go b/src/net/url/url.go index 0931296468..42a514bbc1 100644 --- a/src/net/url/url.go +++ b/src/net/url/url.go @@ -503,6 +503,19 @@ func parse(rawurl string, viaRequest bool) (*URL, error) { if viaRequest { return nil, errors.New("invalid URI for request") } + + // Avoid confusion with malformed schemes, like cache_object:foo/bar. + // See golang.org/issue/16822. + // + // RFC 3986, §3.3: + // In addition, a URI reference (Section 4.1) may be a relative-path reference, + // in which case the first path segment cannot contain a colon (":") character. + colon := strings.Index(rest, ":") + slash := strings.Index(rest, "/") + if colon >= 0 && (slash < 0 || colon < slash) { + // First path segment has colon. Not allowed in relative URL. + return nil, errors.New("first path segment in URL cannot contain colon") + } } if (url.Scheme != "" || !viaRequest && !strings.HasPrefix(rest, "///")) && strings.HasPrefix(rest, "//") { diff --git a/src/net/url/url_test.go b/src/net/url/url_test.go index eebc1112c1..6c3bb21d20 100644 --- a/src/net/url/url_test.go +++ b/src/net/url/url_test.go @@ -1385,7 +1385,7 @@ func TestParseFailure(t *testing.T) { } } -func TestParseAuthority(t *testing.T) { +func TestParseErrors(t *testing.T) { tests := []struct { in string wantErr bool @@ -1405,9 +1405,13 @@ func TestParseAuthority(t *testing.T) { {"http://%41:8080/", true}, // not allowed: % encoding only for non-ASCII {"mysql://x@y(z:123)/foo", false}, // golang.org/issue/12023 {"mysql://x@y(1.2.3.4:123)/foo", false}, - {"mysql://x@y([2001:db8::1]:123)/foo", false}, + {"http://[]%20%48%54%54%50%2f%31%2e%31%0a%4d%79%48%65%61%64%65%72%3a%20%31%32%33%0a%0a/", true}, // golang.org/issue/11208 {"http://a b.com/", true}, // no space in host name please + {"cache_object://foo", true}, // scheme cannot have _, relative path cannot have : in first segment + {"cache_object:foo", true}, + {"cache_object:foo/bar", true}, + {"cache_object/:foo/bar", false}, } for _, tt := range tests { u, err := Parse(tt.in) |