Skip to content

Commit

Permalink
URI.Parse should never change it's input
Browse files Browse the repository at this point in the history
Decode the URI in place, but use the bytes of the URI instead of the
bytes of the input parameter.
  • Loading branch information
erikdubbelboer committed Oct 3, 2021
1 parent ffab77a commit ad6d128
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
11 changes: 8 additions & 3 deletions uri.go
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
20 changes: 20 additions & 0 deletions uri_test.go
Expand Up @@ -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())
}
}

0 comments on commit ad6d128

Please sign in to comment.