@@ -136,13 +136,14 @@ class MultipartState(IntEnum):
136136LOWER_Z = b"z" [0 ]
137137NULL = b"\x00 " [0 ]
138138
139-
140- # Lower-casing a character is different, because of the difference between
141- # str on Py2, and bytes on Py3. Same with getting the ordinal value of a byte,
142- # and joining a list of bytes together.
143- # These functions abstract that.
144- def lower_char (c : int ) -> int :
145- return c | 0x20
139+ # Mask for ASCII characters that can be http tokens.
140+ # Per RFC7230 - 3.2.6, this is all alpha-numeric characters
141+ # and these: !#$%&'*+-.^_`|~
142+ TOKEN_CHARS_SET = frozenset (
143+ b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
144+ b"abcdefghijklmnopqrstuvwxyz"
145+ b"0123456789"
146+ b"!#$%&'*+-.^_`|~" )
146147
147148
148149def ord_char (c : int ) -> int :
@@ -1175,12 +1176,8 @@ def data_callback(name: str, remaining: bool = False) -> None:
11751176 # Increment our index in the header.
11761177 index += 1
11771178
1178- # Do nothing if we encounter a hyphen.
1179- if c == HYPHEN :
1180- pass
1181-
11821179 # If we've reached a colon, we're done with this header.
1183- elif c == COLON :
1180+ if c == COLON :
11841181 # A 0-length header is an error.
11851182 if index == 1 :
11861183 msg = "Found 0-length header at %d" % (i ,)
@@ -1195,16 +1192,12 @@ def data_callback(name: str, remaining: bool = False) -> None:
11951192 # Move to parsing the header value.
11961193 state = MultipartState .HEADER_VALUE_START
11971194
1198- else :
1199- # Lower-case this character, and ensure that it is in fact
1200- # a valid letter. If not, it's an error.
1201- cl = lower_char (c )
1202- if cl < LOWER_A or cl > LOWER_Z :
1203- msg = "Found non-alphanumeric character %r in " "header at %d" % (c , i )
1204- self .logger .warning (msg )
1205- e = MultipartParseError (msg )
1206- e .offset = i
1207- raise e
1195+ elif c not in TOKEN_CHARS_SET :
1196+ msg = "Found invalid character %r in header at %d" % (c , i )
1197+ self .logger .warning (msg )
1198+ e = MultipartParseError (msg )
1199+ e .offset = i
1200+ raise e
12081201
12091202 elif state == MultipartState .HEADER_VALUE_START :
12101203 # Skip leading spaces.
0 commit comments