Skip to content

Commit 41ff30f

Browse files
RealOrangeOnenessita
authored andcommitted
Refs #36520 -- Ensured only the header value is passed to parse_header_parameters for multipart requests.
Header parsing should apply only to the header value. The previous implementation happened to work but relied on unintended behavior.
1 parent c93dddf commit 41ff30f

2 files changed

Lines changed: 31 additions & 4 deletions

File tree

django/http/multipartparser.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -721,11 +721,10 @@ def parse_boundary_stream(stream, max_header_size):
721721

722722
# Eliminate blank lines
723723
for line in header.split(b"\r\n"):
724-
# This terminology ("main value" and "dictionary of
725-
# parameters") is from the Python docs.
726724
try:
727-
main_value_pair, params = parse_header_parameters(line.decode())
728-
name, value = main_value_pair.split(":", 1)
725+
header_name, value_and_params = line.decode().split(":", 1)
726+
name = header_name.lower().rstrip(" ")
727+
value, params = parse_header_parameters(value_and_params.lstrip(" "))
729728
params = {k: v.encode() for k, v in params.items()}
730729
except ValueError: # Invalid header.
731730
continue

tests/requests_tests/tests.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,34 @@ def test_body_after_POST_multipart_form_data(self):
450450
with self.assertRaises(RawPostDataException):
451451
request.body
452452

453+
def test_malformed_multipart_header(self):
454+
for header in [
455+
'Content-Disposition : form-data; name="name"',
456+
'Content-Disposition:form-data; name="name"',
457+
'Content-Disposition :form-data; name="name"',
458+
]:
459+
with self.subTest(header):
460+
payload = FakePayload(
461+
"\r\n".join(
462+
[
463+
"--boundary",
464+
header,
465+
"",
466+
"value",
467+
"--boundary--",
468+
]
469+
)
470+
)
471+
request = WSGIRequest(
472+
{
473+
"REQUEST_METHOD": "POST",
474+
"CONTENT_TYPE": "multipart/form-data; boundary=boundary",
475+
"CONTENT_LENGTH": len(payload),
476+
"wsgi.input": payload,
477+
}
478+
)
479+
self.assertEqual(request.POST, {"name": ["value"]})
480+
453481
def test_body_after_POST_multipart_related(self):
454482
"""
455483
Reading body after parsing multipart that isn't form-data is allowed

0 commit comments

Comments
 (0)