summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJake Howard <git@theorangeone.net>2025-08-20 16:04:48 +0100
committernessita <124304+nessita@users.noreply.github.com>2025-08-28 14:25:36 -0300
commit41ff30f6f9d072036be1f74db8f0c8b21565299f (patch)
treef7b27cbfccf9d019907071a64eaf4e2c70f30c21
parentc93dddf65910eb94bb33d1895ff133cef74a308e (diff)
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.
-rw-r--r--django/http/multipartparser.py7
-rw-r--r--tests/requests_tests/tests.py28
2 files changed, 31 insertions, 4 deletions
diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py
index 531f9a0468..d420c255eb 100644
--- a/django/http/multipartparser.py
+++ b/django/http/multipartparser.py
@@ -721,11 +721,10 @@ def parse_boundary_stream(stream, max_header_size):
# Eliminate blank lines
for line in header.split(b"\r\n"):
- # This terminology ("main value" and "dictionary of
- # parameters") is from the Python docs.
try:
- main_value_pair, params = parse_header_parameters(line.decode())
- name, value = main_value_pair.split(":", 1)
+ header_name, value_and_params = line.decode().split(":", 1)
+ name = header_name.lower().rstrip(" ")
+ value, params = parse_header_parameters(value_and_params.lstrip(" "))
params = {k: v.encode() for k, v in params.items()}
except ValueError: # Invalid header.
continue
diff --git a/tests/requests_tests/tests.py b/tests/requests_tests/tests.py
index 7e615617d7..36843df9b6 100644
--- a/tests/requests_tests/tests.py
+++ b/tests/requests_tests/tests.py
@@ -450,6 +450,34 @@ class RequestsTests(SimpleTestCase):
with self.assertRaises(RawPostDataException):
request.body
+ def test_malformed_multipart_header(self):
+ for header in [
+ 'Content-Disposition : form-data; name="name"',
+ 'Content-Disposition:form-data; name="name"',
+ 'Content-Disposition :form-data; name="name"',
+ ]:
+ with self.subTest(header):
+ payload = FakePayload(
+ "\r\n".join(
+ [
+ "--boundary",
+ header,
+ "",
+ "value",
+ "--boundary--",
+ ]
+ )
+ )
+ request = WSGIRequest(
+ {
+ "REQUEST_METHOD": "POST",
+ "CONTENT_TYPE": "multipart/form-data; boundary=boundary",
+ "CONTENT_LENGTH": len(payload),
+ "wsgi.input": payload,
+ }
+ )
+ self.assertEqual(request.POST, {"name": ["value"]})
+
def test_body_after_POST_multipart_related(self):
"""
Reading body after parsing multipart that isn't form-data is allowed