]> git.ipfire.org Git - thirdparty/starlette.git/commitdiff
Raise `MultiPartException` when missing "name" field on `Content-Disposition` header...
authorMarcelo Trylesinski <marcelotryle@gmail.com>
Tue, 24 May 2022 05:31:57 +0000 (07:31 +0200)
committerGitHub <noreply@github.com>
Tue, 24 May 2022 05:31:57 +0000 (07:31 +0200)
setup.cfg
starlette/formparsers.py
tests/test_formparsers.py

index 734fa818c169a2fd41e554dca01224e63647b08a..8dad329c746ef60d3a8808afcfe4873e389d78e3 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -30,6 +30,7 @@ filterwarnings=
     error
     ignore: run_until_first_complete is deprecated and will be removed in a future version.:DeprecationWarning
     ignore: starlette\.middleware\.wsgi is deprecated and will be removed in a future release\.*:DeprecationWarning
+    ignore: Async generator 'starlette\.requests\.Request\.stream' was garbage collected before it had been exhausted.*:ResourceWarning
 
 [coverage:run]
 source_pkgs = starlette, tests
index 4cde71b676a142bc9b5c00e4622a8a24a1953b3b..53538c814aa4c1d583e998ca57a56ed80e053fc0 100644 (file)
@@ -220,7 +220,13 @@ class MultiPartParser:
                     header_value = b""
                 elif message_type == MultiPartMessage.HEADERS_FINISHED:
                     disposition, options = parse_options_header(content_disposition)
-                    field_name = _user_safe_decode(options[b"name"], charset)
+                    try:
+                        field_name = _user_safe_decode(options[b"name"], charset)
+                    except KeyError:
+                        raise MultiPartException(
+                            'The Content-Disposition header field "name" must be '
+                            "provided."
+                        )
                     if b"filename" in options:
                         filename = _user_safe_decode(options[b"filename"], charset)
                         file = UploadFile(
index 6710595297e4da1a5bc700828e40432ce827408e..7418595cfeb85e79aae2b777e51ec0ee5afd9065 100644 (file)
@@ -418,3 +418,35 @@ def test_missing_boundary_parameter(
         )
         assert res.status_code == 400
         assert res.text == "Missing boundary in multipart."
+
+
+@pytest.mark.parametrize(
+    "app,expectation",
+    [
+        (app, pytest.raises(MultiPartException)),
+        (Starlette(routes=[Mount("/", app=app)]), does_not_raise()),
+    ],
+)
+def test_missing_name_parameter_on_content_disposition(
+    app, expectation, test_client_factory: typing.Callable[..., TestClient]
+):
+    client = test_client_factory(app)
+    with expectation:
+        res = client.post(
+            "/",
+            data=(
+                # data
+                b"--a7f7ac8d4e2e437c877bb7b8d7cc549c\r\n"
+                b'Content-Disposition: form-data; ="field0"\r\n\r\n'
+                b"value0\r\n"
+            ),
+            headers={
+                "Content-Type": (
+                    "multipart/form-data; boundary=a7f7ac8d4e2e437c877bb7b8d7cc549c"
+                )
+            },
+        )
+        assert res.status_code == 400
+        assert (
+            res.text == 'The Content-Disposition header field "name" must be provided.'
+        )