]> Cypherpunks repositories - gostls13.git/commitdiff
net/textproto: permit all valid token chars in CanonicalMIMEHeaderKey input
authorBrad Fitzpatrick <bradfitz@golang.org>
Wed, 20 Jan 2016 06:19:38 +0000 (06:19 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Thu, 25 Feb 2016 21:00:57 +0000 (21:00 +0000)
Fixes #13767

Change-Id: Ib743db7d9d72022ea911bc5ac535243489425642
Reviewed-on: https://go-review.googlesource.com/18725
Reviewed-by: Andrew Gerrand <adg@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/net/textproto/reader.go
src/net/textproto/reader_test.go

index 91bbb573043c77e262e0de5908a22bd363b969fd..109afd3ceaacf5f2576e092db25590dd43671617 100644 (file)
@@ -581,18 +581,14 @@ func CanonicalMIMEHeaderKey(s string) string {
 const toLower = 'a' - 'A'
 
 // validHeaderFieldByte reports whether b is a valid byte in a header
-// field key. This is actually stricter than RFC 7230, which says:
+// field name. RFC 7230 says:
+//   header-field   = field-name ":" OWS field-value OWS
+//   field-name     = token
 //   tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
 //           "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
 //   token = 1*tchar
-// TODO: revisit in Go 1.6+ and possibly expand this. But note that many
-// servers have historically dropped '_' to prevent ambiguities when mapping
-// to CGI environment variables.
 func validHeaderFieldByte(b byte) bool {
-       return ('A' <= b && b <= 'Z') ||
-               ('a' <= b && b <= 'z') ||
-               ('0' <= b && b <= '9') ||
-               b == '-'
+       return int(b) < len(isTokenTable) && isTokenTable[b]
 }
 
 // canonicalMIMEHeaderKey is like CanonicalMIMEHeaderKey but is
@@ -682,3 +678,85 @@ func init() {
                commonHeader[v] = v
        }
 }
+
+// isTokenTable is a copy of net/http/lex.go's isTokenTable.
+// See https://httpwg.github.io/specs/rfc7230.html#rule.token.separators
+var isTokenTable = [127]bool{
+       '!':  true,
+       '#':  true,
+       '$':  true,
+       '%':  true,
+       '&':  true,
+       '\'': true,
+       '*':  true,
+       '+':  true,
+       '-':  true,
+       '.':  true,
+       '0':  true,
+       '1':  true,
+       '2':  true,
+       '3':  true,
+       '4':  true,
+       '5':  true,
+       '6':  true,
+       '7':  true,
+       '8':  true,
+       '9':  true,
+       'A':  true,
+       'B':  true,
+       'C':  true,
+       'D':  true,
+       'E':  true,
+       'F':  true,
+       'G':  true,
+       'H':  true,
+       'I':  true,
+       'J':  true,
+       'K':  true,
+       'L':  true,
+       'M':  true,
+       'N':  true,
+       'O':  true,
+       'P':  true,
+       'Q':  true,
+       'R':  true,
+       'S':  true,
+       'T':  true,
+       'U':  true,
+       'W':  true,
+       'V':  true,
+       'X':  true,
+       'Y':  true,
+       'Z':  true,
+       '^':  true,
+       '_':  true,
+       '`':  true,
+       'a':  true,
+       'b':  true,
+       'c':  true,
+       'd':  true,
+       'e':  true,
+       'f':  true,
+       'g':  true,
+       'h':  true,
+       'i':  true,
+       'j':  true,
+       'k':  true,
+       'l':  true,
+       'm':  true,
+       'n':  true,
+       'o':  true,
+       'p':  true,
+       'q':  true,
+       'r':  true,
+       's':  true,
+       't':  true,
+       'u':  true,
+       'v':  true,
+       'w':  true,
+       'x':  true,
+       'y':  true,
+       'z':  true,
+       '|':  true,
+       '~':  true,
+}
index 9c71594362ebb4be39cfd4e6be1c90203ef43a75..8a07adf4d304296380080859da1e36acf9d5ce7b 100644 (file)
@@ -25,6 +25,12 @@ var canonicalHeaderKeyTests = []canonicalHeaderKeyTest{
        {"user-agent", "User-Agent"},
        {"USER-AGENT", "User-Agent"},
 
+       // Other valid tchar bytes in tokens:
+       {"foo-bar_baz", "Foo-Bar_baz"},
+       {"foo-bar$baz", "Foo-Bar$baz"},
+       {"foo-bar~baz", "Foo-Bar~baz"},
+       {"foo-bar*baz", "Foo-Bar*baz"},
+
        // Non-ASCII or anything with spaces or non-token chars is unchanged:
        {"üser-agenT", "üser-agenT"},
        {"a B", "a B"},