From 39ad0fd0789872f9469167be7fe9578625ff246e Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Fri, 8 Jan 2016 18:30:04 +0000 Subject: [PATCH] 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/18375 Reviewed-by: Russ Cox Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- src/net/http/lex.go | 14 ++++++++++++++ src/net/http/request.go | 18 +++++++++++++++++- src/net/http/serve_test.go | 5 ++++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/net/http/lex.go b/src/net/http/lex.go index 50b14f8b32..52b6481c14 100644 --- a/src/net/http/lex.go +++ b/src/net/http/lex.go @@ -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 = +func isCTL(b byte) bool { + const del = 0x7f // a CTL + return b < ' ' || b == del +} diff --git a/src/net/http/request.go b/src/net/http/request.go index 1a6a97d4d7..c2f5f26a4c 100644 --- a/src/net/http/request.go +++ b/src/net/http/request.go @@ -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 = +// +// http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 : +// +// TEXT = +// LWS = [CRLF] 1*( SP | HT ) +// CTL = 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 } } diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go index be175f8420..f36bb38ba7 100644 --- a/src/net/http/serve_test.go +++ b/src/net/http/serve_test.go @@ -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 { -- 2.48.1