diff options
| author | Jake Howard <git@theorangeone.net> | 2025-08-20 16:04:48 +0100 |
|---|---|---|
| committer | nessita <124304+nessita@users.noreply.github.com> | 2025-08-28 14:25:36 -0300 |
| commit | 41ff30f6f9d072036be1f74db8f0c8b21565299f (patch) | |
| tree | f7b27cbfccf9d019907071a64eaf4e2c70f30c21 | |
| parent | c93dddf65910eb94bb33d1895ff133cef74a308e (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.py | 7 | ||||
| -rw-r--r-- | tests/requests_tests/tests.py | 28 |
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 |
