GeezerVison is showing github.com — [CVE-2025-11468] email preserve parens when folding comments · openSUSE-Python/cpython@632a40d
File treeExpand file treeCollapse file tree Open diff view settings Misc/NEWS.d/next/Security
Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: Lib/email/_header_value_parser.py +23-1Lines changed: 23 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 96 | 96 | NLSET = {'\n', '\r'} | 97 | 97 | SPECIALSNL = SPECIALS | NLSET | 98 | 98 |
| | 99 | +def make_parenthesis_pairs(value): | | 100 | + """Escape parenthesis and backslash for use within a comment.""" | | 101 | + return str(value).replace('\\', '\\\\') \ | | 102 | + .replace('(', '\\(').replace(')', '\\)') | | 103 | + | | 104 | + | 99 | 105 | def quote_string(value): | 100 | 106 | return '"'+str(value).replace('\\', '\\\\').replace('"', r'\"')+'"' | 101 | 107 |
| @@ -931,7 +937,7 @@ def value(self): | 931 | 937 | return ' ' | 932 | 938 |
| 933 | 939 | def startswith_fws(self): | 934 | | - return True | | 940 | + return self and self[0] in WSP | 935 | 941 |
| 936 | 942 |
| 937 | 943 | class ValueTerminal(Terminal): | @@ -2861,6 +2867,22 @@ def _refold_parse_tree(parse_tree, *, policy): | 2861 | 2867 | if not hasattr(part, 'encode'): | 2862 | 2868 | # It's not a terminal, try folding the subparts. | 2863 | 2869 | newparts = list(part) | | 2870 | + if part.token_type == 'bare-quoted-string': | | 2871 | + # To fold a quoted string we need to create a list of terminal | | 2872 | + # tokens that will render the leading and trailing quotes | | 2873 | + # and use quoted pairs in the value as appropriate. | | 2874 | + newparts = ( | | 2875 | + [ValueTerminal('"', 'ptext')] + | | 2876 | + [ValueTerminal(make_quoted_pairs(p), 'ptext') | | 2877 | + for p in newparts] + | | 2878 | + [ValueTerminal('"', 'ptext')]) | | 2879 | + if part.token_type == 'comment': | | 2880 | + newparts = ( | | 2881 | + [ValueTerminal('(', 'ptext')] + | | 2882 | + [ValueTerminal(make_parenthesis_pairs(p), 'ptext') | | 2883 | + if p.token_type == 'ptext' else p | | 2884 | + for p in newparts] + | | 2885 | + [ValueTerminal(')', 'ptext')]) | 2864 | 2886 | if not part.as_ew_allowed: | 2865 | 2887 | wrap_as_ew_blocked += 1 | 2866 | 2888 | newparts.append(end_ew_not_allowed) | |
Collapse file Copy file name to clipboardExpand all lines: Lib/test/test_email/test__header_value_parser.py +23Lines changed: 23 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -2751,6 +2751,29 @@ def test_address_list_with_unicode_names_in_quotes(self): | 2751 | 2751 | | 2752 | 2752 | | 2753 | 2753 |
| | 2754 | + def test_address_list_with_long_unwrapable_comment(self): | | 2755 | + policy = self.policy.clone(max_line_length=40) | | 2756 | + cases = [ | | 2757 | + # (to, folded) | | 2758 | + | | 2759 | + | | 2760 | + | | 2761 | + | | 2762 | + | | 2763 | + | | 2764 | + | | 2765 | + | | 2766 | + | | 2767 | + | | 2768 | + | | 2769 | + | | 2770 | + | | 2771 | + | | 2772 | + ] | | 2773 | + for (to, folded) in cases: | | 2774 | + with self.subTest(to=to): | | 2775 | + self._test(parser.get_address_list(to)[0], folded, policy=policy) | | 2776 | + | 2754 | 2777 | # XXX Need tests with comments on various sides of a unicode token, | 2755 | 2778 | # and with unicode tokens in the comments. Spaces inside the quotes | 2756 | 2779 | # currently don't do the right thing. | |
Collapse file Copy file name to clipboard +6Lines changed: 6 additions & 0 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +Fixed a bug in the folding of comments when flattening an email message | | 2 | +using a modern email policy. Comments consisting of a very long sequence of | | 3 | +non-foldable characters could trigger a forced line wrap that omitted the | | 4 | +required leading space on the continuation line, causing the remainder of | | 5 | +the comment to be interpreted as a new header field. This enabled header | | 6 | +injection with carefully crafted inputs. |
|