GeezerVison is showing github.com — gh-87112: Ensure that only digits convertible to integers are accepted as section number in MIME header parameter by matthieucan · Pull Request #136877 · python/cpython
Conversation
matthieucan
commented
Jul 20, 2025
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
With those changes, the MIME parameter parser discards parameters with an invalid section number that uses a digit not convertible to integer such as super-script "²" or "𐩃" (Kharosthi number).
For backwards compatibility, keep accepting non-ASCII digits that can be converted to integers, such as NKO digits.
Before:
>>> import email.headerregistry
>>> reg = email.headerregistry.HeaderRegistry()
>>> reg('Content-Disposition', 'inline; foo*0=bar')
'inline; foo="bar"'
>>> reg('Content-Disposition', 'inline; foo*X=bar')
'inline;'
>>> reg('Content-Disposition', 'inline; foo*0=bar; foo*߁=baz')
'inline; foo="barbaz"'
>>> reg('Content-Disposition', 'inline; foo*²=bar')
Traceback (most recent call last):
File "<python-input-2>", line 1, in <module>
reg('Content-Disposition', 'inline; foo*²=bar')
~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/matthieu/git/cpython/Lib/email/headerregistry.py", line 604, in __call__
return self[name](name, value)
~~~~~~~~~~^^^^^^^^^^^^^
File "/Users/matthieu/git/cpython/Lib/email/headerregistry.py", line 192, in __new__
cls.parse(value, kwds)
~~~~~~~~~^^^^^^^^^^^^^
File "/Users/matthieu/git/cpython/Lib/email/headerregistry.py", line 448, in parse
kwds['parse_tree'] = parse_tree = cls.value_parser(value)
~~~~~~~~~~~~~~~~^^^^^^^
File "/Users/matthieu/git/cpython/Lib/email/_header_value_parser.py", line 2736, in parse_content_disposition_header
disp_header.append(parse_mime_parameters(value[1:]))
~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
File "/Users/matthieu/git/cpython/Lib/email/_header_value_parser.py", line 2601, in parse_mime_parameters
token, value = get_parameter(value)
~~~~~~~~~~~~~^^^^^^^
File "/Users/matthieu/git/cpython/Lib/email/_header_value_parser.py", line 2464, in get_parameter
token, value = get_section(value)
~~~~~~~~~~~^^^^^^^
File "/Users/matthieu/git/cpython/Lib/email/_header_value_parser.py", line 2417, in get_section
section.number = int(digits)
~~~^^^^^^^^
ValueError: invalid literal for int() with base 10: '²'
After:
>>> import email.headerregistry
>>> reg = email.headerregistry.HeaderRegistry()
>>> reg('Content-Disposition', 'inline; foo*0=bar')
'inline; foo="bar"'
>>> reg('Content-Disposition', 'inline; foo*X=bar')
'inline;'
>>> reg('Content-Disposition', 'inline; foo*0=bar; foo*߁=baz')
'inline; foo="barbaz"'
>>> reg('Content-Disposition', 'inline; foo*²=bar')
'inline;'
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
picnixz
changed the title
gh-87112: Do not fail when non 0-9 digit is used as section number in MIME header parameter
gh-87112: Ensure that only ASCII digits are accepted as section number in MIME header parameter
Jul 20, 2025
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
|
|
"found {}".format(value))
|
|
|
digits = ''
|
|
|
while value and value[0].isdigit():
|
|
|
while value and '0' <= value[0] <= '9':
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
while value and '0' <= value[0] <= '9': |
|
while value and ('0' <= value[0] <= '9'): |
It will a bit clearer. Or you can still use a separate function to make it even cleareer. The bottleneck won't be the function call IMO.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did that, but not the separate function. It was my understanding that @StanFromIreland was leaning towards not having an inner function
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine, I was against the function to check if it is in a dictionary.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! Just moved it to a separate function for extra-clarity
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Could you also test with, for example, ߅ (NKO DIGIT FIVE), which int accepts?
Given that some values worked before, IMO the HeaderParseError should only be raised if int() fails; for other non-ASCII numbers this should append an InvalidHeaderDefect.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Could you also test with, for example, ߅ (NKO DIGIT FIVE), which int accepts? Given that some values worked before, IMO the HeaderParseError should only be raised if int() fails; for other non-ASCII numbers this should append an InvalidHeaderDefect.
Thank you for looking into this.
In my understanding, those are the possible scenarios:
- The section number is made of ASCII digits (
'0' <= d <= '9')
- Valid, remains unchanged with this PR
- The section number is made of digits (
isdigit(d)) which can be converted to integers (int(d)), e.g.߅ (NKO DIGIT FIVE)
- This was accepted before, without a defect
- This PR, in its current state, rejects those (they are ignored and trigger a defect)
- ➡️ ❓ @encukou Do I understand correctly that they should be accepted, and not raise a defect (even if they are not RFC-valid)? Or should they be accepted and raise a defect?
- The section number is made of digits (
isdigit(d)) which cannot be converted to integers (not int(d)), e.g. ²
- This used to fail with a raised exception
- This PR, in its current state, rejects those (they are ignored and trigger a defect)
- The section number is not made of digits (
not isdigit(d))
- Invalid, remains unchanged with this PR
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
The section number is made of digits (isdigit(d)) which can be converted to integers (int(d)), e.g.߅ (NKO DIGIT FIVE). This was accepted before, without a defect
IMO, they should be accepted and raise a defect.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
matthieucan
changed the title
gh-87112: Ensure that only ASCII digits are accepted as section number in MIME header parameter
gh-87112: Ensure that only digits convertible to integers are accepted as section number in MIME header parameter
Jul 27, 2025
The section number is made of digits (isdigit(d)) which can be converted to integers (int(d)), e.g.߅ (NKO DIGIT FIVE). This was accepted before, without a defect
IMO, they should be accepted and raise a defect.
Thank you, I agree. This is now implemented.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
This PR is stale because it has been open for 30 days with no activity.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
I think that what we should to do here is change the incorrect isdigit to isdecimal and add as_ew_allowed=False to MIMEVersion. If I'm reading rfc 6532 correctly (though it is quite possible I'm not) then non-ascii decimal digits are not a defect unless you are serializing to ascii. (They should already show up as non-ascii defects when parsing with utf8=False.) If we make those changes that should eliminate the exception, and the new code proposed in #122540 should raise an error if the header is serialized with utf8=False.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
This PR is stale because it has been open for 90 days with no activity.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Reviewers
picnixz
picnixz left review comments
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|