Commit 39ad0fd0 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

net/http: fix validHeaderValue yet again, excluding the DEL CTL byte

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/18375Reviewed-by: default avatarRuss Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent ecc01a7d
...@@ -167,3 +167,17 @@ func tokenEqual(t1, t2 string) bool { ...@@ -167,3 +167,17 @@ func tokenEqual(t1, t2 string) bool {
} }
return true 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
}
...@@ -1136,10 +1136,26 @@ func validHeaderName(v string) bool { ...@@ -1136,10 +1136,26 @@ func validHeaderName(v string) bool {
return strings.IndexFunc(v, isNotToken) == -1 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 { func validHeaderValue(v string) bool {
for i := 0; i < len(v); i++ { for i := 0; i < len(v); i++ {
b := v[i] b := v[i]
if b < ' ' && b != '\t' { if isCTL(b) && !isLWS(b) {
return false return false
} }
} }
......
...@@ -3798,7 +3798,10 @@ func TestServerValidatesHeaders(t *testing.T) { ...@@ -3798,7 +3798,10 @@ func TestServerValidatesHeaders(t *testing.T) {
{"foo\xffbar: foo\r\n", 400}, // binary in header {"foo\xffbar: foo\r\n", 400}, // binary in header
{"foo\x00bar: 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 {"foo: foo\xfffoo\r\n", 200}, // non-ASCII high octets in value are fine
} }
for _, tt := range tests { for _, tt := range tests {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment