summaryrefslogtreecommitdiffstats
path: root/Lib/email
diff options
context:
space:
mode:
authorKrzysztof Wojcik <wojcikk2903@users.noreply.github.com>2019-05-14 16:55:23 (GMT)
committerVictor Stinner <vstinner@redhat.com>2019-05-14 16:55:23 (GMT)
commitc1f5667be1e3ec5871560c677402c1252c6018a6 (patch)
tree199ab3f8a68ef855b41a086ce280faff1ca817bf /Lib/email
parent4d45a3b1107977baba9dce868e80d1d95bce4085 (diff)
downloadcpython-c1f5667be1e3ec5871560c677402c1252c6018a6.zip
cpython-c1f5667be1e3ec5871560c677402c1252c6018a6.tar.gz
cpython-c1f5667be1e3ec5871560c677402c1252c6018a6.tar.bz2
bpo-33529, email: Fix infinite loop in email header encoding (GH-12020)
Diffstat (limited to 'Lib/email')
-rw-r--r--Lib/email/_header_value_parser.py23
1 files changed, 13 insertions, 10 deletions
diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py
index bb26d5a..60d0d32 100644
--- a/Lib/email/_header_value_parser.py
+++ b/Lib/email/_header_value_parser.py
@@ -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])