diff --git a/CHANGES/13009.bugfix.rst b/CHANGES/13009.bugfix.rst new file mode 100644 index 00000000000..f7faff672f0 --- /dev/null +++ b/CHANGES/13009.bugfix.rst @@ -0,0 +1 @@ +Fixed :py:func:`~aiohttp.helpers.parse_mimetype` inserting a spurious empty-key diff --git a/aiohttp/helpers.py b/aiohttp/helpers.py index 2fa8a19b6a7..65bc269e1da 100644 --- a/aiohttp/helpers.py +++ b/aiohttp/helpers.py @@ -332,7 +332,7 @@ def parse_mimetype(mimetype: str) -> MimeType: parts = mimetype.split(";") params: MultiDict[str] = MultiDict() for item in parts[1:]: - if not item: + if not item.strip(): continue key, _, value = item.partition("=") params.add(key.lower().strip(), value.strip(' "')) diff --git a/tests/test_helpers.py b/tests/test_helpers.py index a499746607a..7f05c144385 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -83,6 +83,33 @@ def test_parse_mimetype(mimetype: str, expected: helpers.MimeType) -> None: assert result == expected +@pytest.mark.parametrize( + "mimetype", + [ + "text/html; ", + "text/html; ", + "text/html;\t", + "text/html; \t", + "text/html; charset=utf-8; ", + "text/html; charset=utf-8;\t\t", + ], +) +def test_parse_mimetype_skips_whitespace_only_segments( + mimetype: str, +) -> None: + # https://github.com/aio-libs/aiohttp/issues/13009 + # A trailing ';' followed by whitespace (e.g. 'text/html; ') was being + # treated as a parameter with an empty key, producing {'': ''} in the + # parsed parameters. RFC 2045 says whitespace-only segments after a ';' + # are not valid parameters; a bare trailing ';' was already skipped + # because it becomes an empty string, but 'text/html; ' was truthy + # and slipped through. + result = helpers.parse_mimetype(mimetype) + assert "" not in result.parameters + if "charset=utf-8" in mimetype: + assert result.parameters.get("charset") == "utf-8" + + # ------------------- parse_content_type ------------------------------