mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
[3.11] gh-80222: Fix email address header folding with long quoted-string (GH-122753) (#129009)
Email generators using email.policy.default could incorrectly omit the
quote ('"') characters from a quoted-string during header refolding,
leading to invalid address headers and enabling header spoofing. This
change restores the quote characters on a bare-quoted-string as the
header is refolded, and escapes backslash and quote chars in the string.
(cherry picked from commit 5aaf416858
)
Co-authored-by: Mike Edmunds <medmunds@gmail.com>
Co-authored-by: Petr Viktorin <encukou@gmail.com>
This commit is contained in:
parent
9d727fe739
commit
7cff053efe
3 changed files with 53 additions and 3 deletions
|
@ -95,8 +95,16 @@ EXTENDED_ATTRIBUTE_ENDS = ATTRIBUTE_ENDS - set('%')
|
|||
NLSET = {'\n', '\r'}
|
||||
SPECIALSNL = SPECIALS | NLSET
|
||||
|
||||
|
||||
def make_quoted_pairs(value):
|
||||
"""Escape dquote and backslash for use within a quoted-string."""
|
||||
return str(value).replace('\\', '\\\\').replace('"', '\\"')
|
||||
|
||||
|
||||
def quote_string(value):
|
||||
return '"'+str(value).replace('\\', '\\\\').replace('"', r'\"')+'"'
|
||||
escaped = make_quoted_pairs(value)
|
||||
return f'"{escaped}"'
|
||||
|
||||
|
||||
# Match a RFC 2047 word, looks like =?utf-8?q?someword?=
|
||||
rfc2047_matcher = re.compile(r'''
|
||||
|
@ -2866,6 +2874,15 @@ def _refold_parse_tree(parse_tree, *, policy):
|
|||
if not hasattr(part, 'encode'):
|
||||
# It's not a terminal, try folding the subparts.
|
||||
newparts = list(part)
|
||||
if part.token_type == 'bare-quoted-string':
|
||||
# To fold a quoted string we need to create a list of terminal
|
||||
# tokens that will render the leading and trailing quotes
|
||||
# and use quoted pairs in the value as appropriate.
|
||||
newparts = (
|
||||
[ValueTerminal('"', 'ptext')] +
|
||||
[ValueTerminal(make_quoted_pairs(p), 'ptext')
|
||||
for p in newparts] +
|
||||
[ValueTerminal('"', 'ptext')])
|
||||
if not part.as_ew_allowed:
|
||||
wrap_as_ew_blocked += 1
|
||||
newparts.append(end_ew_not_allowed)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue