]> Cypherpunks repositories - gostls13.git/commitdiff
net/url, net/http: relax CTL-in-URL validation to only ASCII CTLs
authorBrad Fitzpatrick <bradfitz@golang.org>
Tue, 29 Jan 2019 17:22:36 +0000 (17:22 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 29 Jan 2019 20:42:54 +0000 (20:42 +0000)
CL 159157 was doing UTF-8 decoding of URLs. URLs aren't really UTF-8,
even if sometimes they are in some contexts.

Instead, only reject ASCII CTLs.

Updates #27302
Updates #22907

Change-Id: Ibd64efa5d3a93263d175aadf1c9f87deb4670c62
Reviewed-on: https://go-review.googlesource.com/c/160178
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/net/http/http.go
src/net/http/request.go
src/net/url/url.go
src/net/url/url_test.go

index 5c03c16c873cd263167b167868daf758d57f24bd..e5d59e14120baa18eeea51f2c8ea76072124aa26 100644 (file)
@@ -59,10 +59,15 @@ func isASCII(s string) bool {
        return true
 }
 
-// isCTL reports whether r is an ASCII control character, including
-// the Extended ASCII control characters included in Unicode.
-func isCTL(r rune) bool {
-       return r < ' ' || 0x7f <= r && r <= 0x9f
+// stringContainsCTLByte reports whether s contains any ASCII control character.
+func stringContainsCTLByte(s string) bool {
+       for i := 0; i < len(s); i++ {
+               b := s[i]
+               if b < ' ' || b == 0x7f {
+                       return true
+               }
+       }
+       return false
 }
 
 func hexEscapeNonASCII(s string) string {
index 01ba1dc1fb1fbe3f724d66952522ac20433b816c..dcad2b6fab366dd631a656a9957f0cc29c947474 100644 (file)
@@ -550,7 +550,7 @@ func (r *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, waitF
                        ruri = r.URL.Opaque
                }
        }
-       if strings.IndexFunc(ruri, isCTL) != -1 {
+       if stringContainsCTLByte(ruri) {
                return errors.New("net/http: can't write control character in Request.URL")
        }
        // TODO: validate r.Method too? At least it's less likely to
index 77078ade1bd962623d1a5569315b57c2244f5494..64274a0a364d0c2ae3ec60bc41c1c9d3c8f3a390 100644 (file)
@@ -513,7 +513,7 @@ func parse(rawurl string, viaRequest bool) (*URL, error) {
        var rest string
        var err error
 
-       if strings.IndexFunc(rawurl, isCTL) != -1 {
+       if stringContainsCTLByte(rawurl) {
                return nil, errors.New("net/url: invalid control character in URL")
        }
 
@@ -1139,8 +1139,13 @@ func validUserinfo(s string) bool {
        return true
 }
 
-// isCTL reports whether r is an ASCII control character, including
-// the Extended ASCII control characters included in Unicode.
-func isCTL(r rune) bool {
-       return r < ' ' || 0x7f <= r && r <= 0x9f
+// stringContainsCTLByte reports whether s contains any ASCII control character.
+func stringContainsCTLByte(s string) bool {
+       for i := 0; i < len(s); i++ {
+               b := s[i]
+               if b < ' ' || b == 0x7f {
+                       return true
+               }
+       }
+       return false
 }
index 43d77f090c96adb46e83ee29a74cf9743b5748c7..c5fc90d5156fd9f0a73b1dc3066abf9355ffddb6 100644 (file)
@@ -1757,6 +1757,12 @@ func TestRejectControlCharacters(t *testing.T) {
                        t.Errorf("Parse(%q) error = %q; want substring %q", s, got, wantSub)
                }
        }
+
+       // But don't reject non-ASCII CTLs, at least for now:
+       if _, err := Parse("http://foo.com/ctl\x80"); err != nil {
+               t.Errorf("error parsing URL with non-ASCII control byte: %v", err)
+       }
+
 }
 
 var escapeBenchmarks = []struct {