diff --git a/uri.go b/uri.go index 061e11edf8..2285f45d0d 100644 --- a/uri.go +++ b/uri.go @@ -305,11 +305,12 @@ func (u *URI) parse(host, uri []byte, isTLS bool) error { } } - host, err := parseHost(host) - if err != nil { + u.host = append(u.host, host...) + if parsedHost, err := parseHost(u.host); err != nil { return err + } else { + u.host = parsedHost } - u.host = append(u.host, host...) lowercaseBytes(u.host) b := uri @@ -353,6 +354,8 @@ func (u *URI) parse(host, uri []byte, isTLS bool) error { // information. That is, as host[:port]. // // Based on https://github.com/golang/go/blob/8ac5cbe05d61df0a7a7c9a38ff33305d4dcfea32/src/net/url/url.go#L619 +// +// The host is parsed and unescaped in place overwriting the contents of the host parameter. func parseHost(host []byte) ([]byte, error) { if len(host) > 0 && host[0] == '[' { // Parse an IP-Literal in RFC 3986 and RFC 6874. @@ -425,6 +428,8 @@ func (e InvalidHostError) Error() string { // which section of the URL string is being unescaped. // // Based on https://github.com/golang/go/blob/8ac5cbe05d61df0a7a7c9a38ff33305d4dcfea32/src/net/url/url.go#L199 +// +// Unescapes in place overwriting the contents of s and returning it. func unescape(s []byte, mode encoding) ([]byte, error) { // Count %, check that they're well-formed. n := 0 diff --git a/uri_test.go b/uri_test.go index 481b51a98d..fc0b2ef0cd 100644 --- a/uri_test.go +++ b/uri_test.go @@ -427,3 +427,23 @@ func TestInvalidUrl(t *testing.T) { t.Fail() } } + +func TestNoOverwriteInput(t *testing.T) { + str := `//%AA` + url := []byte(str) + + u := AcquireURI() + defer ReleaseURI(u) + + if err := u.Parse(nil, url); err != nil { + t.Error(err) + } + + if string(url) != str { + t.Error() + } + + if u.String() != "http://\xaa/" { + t.Errorf("%q", u.String()) + } +}