diff --git a/django/utils/http.py b/django/utils/http.py index 3d5b7b6be6aa..a892221f0190 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -420,7 +420,7 @@ def content_disposition_header(as_attachment, filename): # characters from 0x21 to 0x7e, except 0x22 (`"`) and 0x5C (`\`) which # can still be expressed but must be escaped with their own `\`. # https://datatracker.ietf.org/doc/html/rfc9110#name-quoted-strings - quotable_characters = r"^[\t \x21-\x7e]*$" + quotable_characters = r"^[\t \x21-\x7e]*\Z" if is_ascii and re.match(quotable_characters, filename): file_expr = 'filename="{}"'.format( filename.replace("\\", "\\\\").replace('"', r"\"") diff --git a/tests/utils_tests/test_http.py b/tests/utils_tests/test_http.py index f7525885c2d2..82ce14721334 100644 --- a/tests/utils_tests/test_http.py +++ b/tests/utils_tests/test_http.py @@ -644,6 +644,8 @@ def test_basic(self): "attachment; filename*=utf-8''%22esp%C3%A9cimen%22%20filename", ), ((True, "some\nfile"), "attachment; filename*=utf-8''some%0Afile"), + ((True, "\n"), "attachment; filename*=utf-8''%0A"), + ((True, "example\n"), "attachment; filename*=utf-8''example%0A"), ) for (is_attachment, filename), expected in tests: