The reason will be displayed to describe this comment to others. Learn more.
Do you mind to elaborate? It's a keyword-only parameter. It sounds very unlikely that someone calls this function with strict=True since the parameter doesn't exist anymore. I don't see the addition of this parameter as a backward incompatible change.
The incompatible change is obviously the fact the emails accepted previously are now rejected.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
The reason will be displayed to describe this comment to others. Learn more.
The incompatible change is obviously the fact the emails accepted previously are now rejected.
Yes.
If the default stayed strict=False, or to only warn by default on invalid addresses (for 2 releases), this would match the process in PEP 387. With strict=True, it seems that you'll need a SC exception for backwards incompatible behaviour -- and that can take time.
Or do you consider this a plain bug fix? In that case, why preserve the old behaviour?
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
The reason will be displayed to describe this comment to others. Learn more.
This change falls into the "unfortunately interesting" category of being unsure we're doing everything correctly so it provides an opt-out. If we have confidence in our change and test suite of valid and invalid email address coverage we could proceed without the behavior flag.
Do we have such confidence?
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
The reason will be displayed to describe this comment to others. Learn more.
I have 0% confience that this change make the parser fully compatible with all RFC. I have 100% confidence that this change rejects email addresses which were accepted before.
Sorry, as I wrote before, the whole parser should be rewritten from scratch to use grammar suggested by RFC, rather than the current design.
This change only make the situation "less bad".
Also it's common that when Python becomes stricter, someone comes and explain their valid use case relying on the old behaviour.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
All reactions
Parse address -- which should be the value of some address-containing field such
as :mailheader:`To` or :mailheader:`Cc` -- into its constituent *realname* and
*email address* parts. Returns a tuple of that information, unless the parse
fails, in which case a 2-tuple of ``('', '')`` is returned.
If *strict* is true, use a strict parser which rejects malformed inputs.
Comment thread
vstinner marked this conversation as resolved.
Resolved
Uh oh!
There was an error while loading. Please reload this page.
The reason will be displayed to describe this comment to others. Learn more.
Alpha versions do not exist for common user, so I would use the 3.12.x version in which the fix will occur in the main branch too. It will help users that drop support of 3.11.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
The reason will be displayed to describe this comment to others. Learn more.
I agree with the concept but that depends on the backport situation. It is fair to start with 3.13 here and if we do decide to backport it further as a security fix later on, the docs can be updated to say 3.12.x.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
vstinner reacted with thumbs up emoji
All reactions
👍1 reaction
Add *strict* optional parameter and reject malformed inputs by default.
Perhaps functions that use _iter_escaped_chars() can also be written using efficient regular expressions to avoid handling ever char separately. For example, _strip_quoted_realnames() could use r'(?s)(?:\\.|[^"])*|(")' or something like.
But do what looks good to you, I can optimize it later.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
The reason will be displayed to describe this comment to others. Learn more.
Perhaps functions that use _iter_escaped_chars() can also be written using efficient regular expressions to avoid handling ever char separately.
This PR is based on PR #108250 which uses the following code to strip quoted real names:
# When a comma is used in the Real Name part it is not a deliminator# So strip those out before counting the commaspattern=r'"[^"]*,[^"]*"'
...
forvinfieldvalues:
v=re.sub(pattern, '', v)
...
But this regular expression doesn't handle escape quote character (\"). So I wrote _strip_quoted_realnames() to replace this invalid regex.
I'm not comfortable with regex to write a parser when the grammar is that complicated. For example, antislash can also be escaped: \\. I didn't check RFC carefully. I mostly tried to support escaped quote character (\").
Also, my priority here is more to get a fix as soon as possible, since the vulnerability was reported in March, and I have to fix the CVE at work as soon as possible.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
All reactions
pos = 0
escape = False
for pos, ch in enumerate(addr):
if escape:
yield (pos, '\\' + ch)
escape = False
elif ch == '\\':
escape = True
else:
yield (pos, ch)
if escape:
yield (pos, '\\')
def _strip_quoted_realnames(addr):
"""Strip real names between quotes."""
if '"' not in addr:
# Fast path
return addr
start = 0
open_pos = None
result = []
for pos, ch in _iter_escaped_chars(addr):
if ch == '"':
if open_pos is None:
open_pos = pos
else:
if start != open_pos:
result.append(addr[start:open_pos])
start = pos + 1
open_pos = None
if start < len(addr):
result.append(addr[start:])
return ''.join(result)
Comment thread
vstinner marked this conversation as resolved.
Resolved
Uh oh!
There was an error while loading. Please reload this page.
def getaddresses(fieldvalues):
"""Return a list of (REALNAME, EMAIL) for each fieldvalue."""
all = COMMASPACE.join(str(v) for v in fieldvalues)
a = _AddressList(all)
return a.addresslist
supports_strict_parsing = True
def getaddresses(fieldvalues, *, strict=True):
"""Return a list of (REALNAME, EMAIL) or ('','') for each fieldvalue.
When parsing fails for a fieldvalue, a 2-tuple of ('', '') is returned in
its place.
If strict is true, use a strict parser which rejects malformed inputs.
"""
# If strict is true, if the resulting list of parsed addresses is greater
# than the number of fieldvalues in the input list, a parsing error has
# occurred and consequently a list containing a single empty 2-tuple [('',
# '')] is returned in its place. This is done to avoid invalid output.
The reason will be displayed to describe this comment to others. Learn more.
_post_parse_validation() output should be a list. There is no advantage to convert it to a generator.
If _pre_parse_validation() becomes a generator, parseaddr() has to create a list anyway for list[0]. getaddresses() cannot use a generator for _pre_parse_validation() result neither, since it consumes fieldvalues twice.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
All reactions
accepted_values = []
# The parser would have parsed a correctly formatted domain-literal
# The existence of an [ after parsing indicates a parsing failure
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.