Skip to content

Commit f12e424

Browse files
committed
Accept digits that are convertible to int for backwards compatibility
1 parent 54bbbb7 commit f12e424

2 files changed

Lines changed: 24 additions & 7 deletions

File tree

Lib/email/_header_value_parser.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2398,21 +2398,31 @@ def get_section(value):
23982398
The caller should already have dealt with leading CFWS.
23992399
24002400
"""
2401-
def is_ascii_digit(d):
2402-
# We don't use str.isdigit because only ASCII digits are allowed.
2403-
return '0' <= d <= '9'
2401+
def is_accepted_digit(d):
2402+
# While only ASCII digits are allowed by the RFC, we accept any digit
2403+
# that can be converted to an int for backwards compatibility purposes.
2404+
# We don't use str.isdigit() as some Unicode digits are not convertible
2405+
# (e.g. superscript digits).
2406+
try:
2407+
int(d)
2408+
return True
2409+
except ValueError:
2410+
return False
24042411

24052412
section = Section()
24062413
if not value or value[0] != '*':
24072414
raise errors.HeaderParseError("Expected section but found {}".format(
24082415
value))
24092416
section.append(ValueTerminal('*', 'section-marker'))
24102417
value = value[1:]
2411-
if not value or not is_ascii_digit(value[0]):
2418+
if not value or not is_accepted_digit(value[0]):
24122419
raise errors.HeaderParseError("Expected section number but "
24132420
"found {}".format(value))
24142421
digits = ''
2415-
while value and is_ascii_digit(value[0]):
2422+
while value and is_accepted_digit(value[0]):
2423+
if not '0' <= value[0] <= '9':
2424+
section.defects.append(errors.InvalidHeaderDefect(
2425+
"section number has a non-ASCII digit {}".format(value[0])))
24162426
digits += value[0]
24172427
value = value[1:]
24182428
if digits[0] == '0' and digits != '0':

Lib/test/test_email/test__header_value_parser.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2983,13 +2983,20 @@ def mime_parameters_as_value(self,
29832983
[('r', '"')],
29842984
[errors.InvalidHeaderDefect]*2),
29852985

2986-
# gh-87112: Only ASCII digits can be section numbers.
2987-
'non_allowed_digits': (
2986+
# gh-87112: Only digits convertible to integers can be section numbers.
2987+
'non_accepted_digit': (
29882988
'foo*0=bar; foo*²=baz',
29892989
' foo="bar"',
29902990
'foo*0=bar; foo*²=baz',
29912991
[('foo', 'bar')],
29922992
[errors.InvalidHeaderDefect]),
2993+
2994+
'non_ascii_digit_backwards_compatibility': (
2995+
'foo*0=bar; foo*߁=baz', # NKO digit '1'
2996+
' foo="barbaz"',
2997+
'foo*0=bar; foo*߁=baz',
2998+
[('foo', 'barbaz')],
2999+
[errors.InvalidHeaderDefect]),
29933000
}
29943001

29953002
@parameterize

0 commit comments

Comments
 (0)