mirror of https://github.com/python/cpython
bpo-33529, email: Fix infinite loop in email header encoding (GH-12020)
This commit is contained in:
parent
4d45a3b110
commit
c1f5667be1
|
@ -2723,16 +2723,19 @@ def _fold_as_ew(to_encode, lines, maxlen, last_ew, ew_combine_allowed, charset):
|
|||
lines.append(' ')
|
||||
# XXX We'll get an infinite loop here if maxlen is <= 7
|
||||
continue
|
||||
first_part = to_encode[:text_space]
|
||||
ew = _ew.encode(first_part, charset=encode_as)
|
||||
excess = len(ew) - remaining_space
|
||||
if excess > 0:
|
||||
# encode always chooses the shortest encoding, so this
|
||||
# is guaranteed to fit at this point.
|
||||
first_part = first_part[:-excess]
|
||||
ew = _ew.encode(first_part)
|
||||
lines[-1] += ew
|
||||
to_encode = to_encode[len(first_part):]
|
||||
|
||||
to_encode_word = to_encode[:text_space]
|
||||
encoded_word = _ew.encode(to_encode_word, charset=encode_as)
|
||||
excess = len(encoded_word) - remaining_space
|
||||
while excess > 0:
|
||||
# Since the chunk to encode is guaranteed to fit into less than 100 characters,
|
||||
# shrinking it by one at a time shouldn't take long.
|
||||
to_encode_word = to_encode_word[:-1]
|
||||
encoded_word = _ew.encode(to_encode_word, charset=encode_as)
|
||||
excess = len(encoded_word) - remaining_space
|
||||
lines[-1] += encoded_word
|
||||
to_encode = to_encode[len(to_encode_word):]
|
||||
|
||||
if to_encode:
|
||||
lines.append(' ')
|
||||
new_last_ew = len(lines[-1])
|
||||
|
|
|
@ -1643,10 +1643,10 @@ class TestFolding(TestHeaderBase):
|
|||
self.assertEqual(
|
||||
h.fold(policy=policy.default),
|
||||
'X-Report-Abuse: =?utf-8?q?=3Chttps=3A//www=2Emailitapp=2E'
|
||||
'com/report=5F?=\n'
|
||||
' =?utf-8?q?abuse=2Ephp=3Fmid=3Dxxx-xxx-xxxx'
|
||||
'xxxxxxxxxxxxxxxxxxxx=3D=3D-xxx-?=\n'
|
||||
' =?utf-8?q?xx-xx=3E?=\n')
|
||||
'com/report=5Fabuse?=\n'
|
||||
' =?utf-8?q?=2Ephp=3Fmid=3Dxxx-xxx-xxxx'
|
||||
'xxxxxxxxxxxxxxxxxxxx=3D=3D-xxx-xx-xx?=\n'
|
||||
' =?utf-8?q?=3E?=\n')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -237,6 +237,14 @@ class PolicyAPITests(unittest.TestCase):
|
|||
email.policy.EmailPolicy.header_factory)
|
||||
self.assertEqual(newpolicy.__dict__, {'raise_on_defect': True})
|
||||
|
||||
def test_non_ascii_chars_do_not_cause_inf_loop(self):
|
||||
policy = email.policy.default.clone(max_line_length=20)
|
||||
actual = policy.fold('Subject', 'ą' * 12)
|
||||
self.assertEqual(
|
||||
actual,
|
||||
'Subject: \n' +
|
||||
12 * ' =?utf-8?q?=C4=85?=\n')
|
||||
|
||||
# XXX: Need subclassing tests.
|
||||
# For adding subclassed objects, make sure the usual rules apply (subclass
|
||||
# wins), but that the order still works (right overrides left).
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Prevent fold function used in email header encoding from entering infinite
|
||||
loop when there are too many non-ASCII characters in a header.
|
Loading…
Reference in New Issue