]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: fix validHeaderValue yet again, excluding the DEL CTL byte
authorBrad Fitzpatrick <bradfitz@golang.org>
Fri, 8 Jan 2016 18:30:04 +0000 (18:30 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Fri, 8 Jan 2016 19:01:32 +0000 (19:01 +0000)
Third time's a charm.

Thanks to Ralph Corderoy for noticing the DEL omission.

Update #11207

Change-Id: I174fd01eaecceae1eb220f2c9136e12d40fbe943
Reviewed-on: https://go-review.googlesource.com/18375
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/net/http/lex.go
src/net/http/request.go
src/net/http/serve_test.go

index 50b14f8b32587b07e0db73f68ca155b1ce2adc46..52b6481c14e725b2229e91916c1298e55b4a3cff 100644 (file)
@@ -167,3 +167,17 @@ func tokenEqual(t1, t2 string) bool {
        }
        return true
 }
+
+// isLWS reports whether b is linear white space, according
+// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
+//      LWS            = [CRLF] 1*( SP | HT )
+func isLWS(b byte) bool { return b == ' ' || b == '\t' }
+
+// isCTL reports whether b is a control byte, according
+// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
+//      CTL            = <any US-ASCII control character
+//                       (octets 0 - 31) and DEL (127)>
+func isCTL(b byte) bool {
+       const del = 0x7f // a CTL
+       return b < ' ' || b == del
+}
index 1a6a97d4d7f2350b0a4a2990d3d32695278ff3cf..c2f5f26a4c1db89e23c384b0af9e9080f736a8c6 100644 (file)
@@ -1136,10 +1136,26 @@ func validHeaderName(v string) bool {
        return strings.IndexFunc(v, isNotToken) == -1
 }
 
+// validHeaderValue reports whether v is a valid "field-value" according to
+// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 :
+//
+//        message-header = field-name ":" [ field-value ]
+//        field-value    = *( field-content | LWS )
+//        field-content  = <the OCTETs making up the field-value
+//                         and consisting of either *TEXT or combinations
+//                         of token, separators, and quoted-string>
+//
+// http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 :
+//
+//        TEXT           = <any OCTET except CTLs,
+//                          but including LWS>
+//        LWS            = [CRLF] 1*( SP | HT )
+//        CTL            = <any US-ASCII control character
+//                         (octets 0 - 31) and DEL (127)>
 func validHeaderValue(v string) bool {
        for i := 0; i < len(v); i++ {
                b := v[i]
-               if b < ' ' && b != '\t' {
+               if isCTL(b) && !isLWS(b) {
                        return false
                }
        }
index be175f8420b5f158f0e0197a33eedd38c4f47b52..f36bb38ba7d12aaf57fd0fbf627545d146db5bfd 100644 (file)
@@ -3798,7 +3798,10 @@ func TestServerValidatesHeaders(t *testing.T) {
                {"foo\xffbar: foo\r\n", 400}, // binary in header
                {"foo\x00bar: foo\r\n", 400}, // binary in header
 
-               {"foo: foo\x00foo\r\n", 400}, // CTL in value is bad
+               {"foo: foo foo\r\n", 200},    // LWS space is okay
+               {"foo: foo\tfoo\r\n", 200},   // LWS tab is okay
+               {"foo: foo\x00foo\r\n", 400}, // CTL 0x00 in value is bad
+               {"foo: foo\x7ffoo\r\n", 400}, // CTL 0x7f in value is bad
                {"foo: foo\xfffoo\r\n", 200}, // non-ASCII high octets in value are fine
        }
        for _, tt := range tests {