GeezerVison is showing github.com — gh-143935: Email preserve parens when folding comments (#143936) · ActiveState/cpython@17d1490
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 +14-1Lines changed: 14 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -101,6 +101,12 @@ def make_quoted_pairs(value): | 101 | 101 | return str(value).replace('\\', '\\\\').replace('"', '\\"') | 102 | 102 |
| 103 | 103 |
| | 104 | +def make_parenthesis_pairs(value): | | 105 | + """Escape parenthesis and backslash for use within a comment.""" | | 106 | + return str(value).replace('\\', '\\\\') \ | | 107 | + .replace('(', '\\(').replace(')', '\\)') | | 108 | + | | 109 | + | 104 | 110 | def quote_string(value): | 105 | 111 | escaped = make_quoted_pairs(value) | 106 | 112 | return f'"{escaped}"' | @@ -943,7 +949,7 @@ def value(self): | 943 | 949 | return ' ' | 944 | 950 |
| 945 | 951 | def startswith_fws(self): | 946 | | - return True | | 952 | + return self and self[0] in WSP | 947 | 953 |
| 948 | 954 |
| 949 | 955 | class ValueTerminal(Terminal): | @@ -2963,6 +2969,13 @@ def _refold_parse_tree(parse_tree, *, policy): | 2963 | 2969 | [ValueTerminal(make_quoted_pairs(p), 'ptext') | 2964 | 2970 | for p in newparts] + | 2965 | 2971 | [ValueTerminal('"', 'ptext')]) | | 2972 | + if part.token_type == 'comment': | | 2973 | + newparts = ( | | 2974 | + [ValueTerminal('(', 'ptext')] + | | 2975 | + [ValueTerminal(make_parenthesis_pairs(p), 'ptext') | | 2976 | + if p.token_type == 'ptext' else p | | 2977 | + for p in newparts] + | | 2978 | + [ValueTerminal(')', 'ptext')]) | 2966 | 2979 | if not part.as_ew_allowed: | 2967 | 2980 | wrap_as_ew_blocked += 1 | 2968 | 2981 | 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 |
|---|
@@ -3294,6 +3294,29 @@ def test_address_list_with_specials_in_long_quoted_string(self): | 3294 | 3294 | with self.subTest(to=to): | 3295 | 3295 | self._test(parser.get_address_list(to)[0], folded, policy=policy) | 3296 | 3296 |
| | 3297 | + def test_address_list_with_long_unwrapable_comment(self): | | 3298 | + policy = self.policy.clone(max_line_length=40) | | 3299 | + cases = [ | | 3300 | + # (to, folded) | | 3301 | + | | 3302 | + | | 3303 | + | | 3304 | + | | 3305 | + | | 3306 | + | | 3307 | + | | 3308 | + | | 3309 | + | | 3310 | + | | 3311 | + | | 3312 | + | | 3313 | + | | 3314 | + | | 3315 | + ] | | 3316 | + for (to, folded) in cases: | | 3317 | + with self.subTest(to=to): | | 3318 | + self._test(parser.get_address_list(to)[0], folded, policy=policy) | | 3319 | + | 3297 | 3320 | # XXX Need tests with comments on various sides of a unicode token, | 3298 | 3321 | # and with unicode tokens in the comments. Spaces inside the quotes | 3299 | 3322 | # 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. |
|