diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py index 91243378dc0441..8684bdb8dfd5c6 100644 --- a/Lib/email/_header_value_parser.py +++ b/Lib/email/_header_value_parser.py @@ -2398,17 +2398,31 @@ def get_section(value): The caller should already have dealt with leading CFWS. """ + def is_accepted_digit(d): + # While only ASCII digits are allowed by the RFC, we accept any digit + # that can be converted to an int for backwards compatibility purposes. + # We don't use str.isdigit() as some Unicode digits are not convertible + # (e.g. superscript digits). + try: + int(d) + return True + except ValueError: + return False + section = Section() if not value or value[0] != '*': raise errors.HeaderParseError("Expected section but found {}".format( value)) section.append(ValueTerminal('*', 'section-marker')) value = value[1:] - if not value or not value[0].isdigit(): + if not value or not is_accepted_digit(value[0]): raise errors.HeaderParseError("Expected section number but " "found {}".format(value)) digits = '' - while value and value[0].isdigit(): + while value and is_accepted_digit(value[0]): + if not '0' <= value[0] <= '9': + section.defects.append(errors.InvalidHeaderDefect( + "section number has a non-ASCII digit {}".format(value[0]))) digits += value[0] value = value[1:] if digits[0] == '0' and digits != '0': diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py index 179e236ecdfd7f..2eaf73bad89afa 100644 --- a/Lib/test/test_email/test__header_value_parser.py +++ b/Lib/test/test_email/test__header_value_parser.py @@ -2982,6 +2982,21 @@ def mime_parameters_as_value(self, 'r*=\'a\'"', [('r', '"')], [errors.InvalidHeaderDefect]*2), + + # gh-87112: Only digits convertible to integers can be section numbers. + 'non_accepted_digit': ( + 'foo*0=bar; foo*²=baz', + ' foo="bar"', + 'foo*0=bar; foo*²=baz', + [('foo', 'bar')], + [errors.InvalidHeaderDefect]), + + 'non_ascii_digit_backwards_compatibility': ( + 'foo*0=bar; foo*߁=baz', # NKO digit '1' + ' foo="barbaz"', + 'foo*0=bar; foo*߁=baz', + [('foo', 'barbaz')], + [errors.InvalidHeaderDefect]), } @parameterize diff --git a/Misc/NEWS.d/next/Library/2025-07-20-17-57-39.gh-issue-87112.sKU2V8.rst b/Misc/NEWS.d/next/Library/2025-07-20-17-57-39.gh-issue-87112.sKU2V8.rst new file mode 100644 index 00000000000000..ba4e72de85e317 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-07-20-17-57-39.gh-issue-87112.sKU2V8.rst @@ -0,0 +1,2 @@ +Ensure that only digits convertible to integers are accepted as section number +in MIME header parameter. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy