Skip to content

Commit bcb6b45

Browse files
authored
gh-134151 Fix TypeError in email.utils.decode_params when sorting RFC 2231 continuations (#134687)
- Fix sorting logic in `email.utils.decode_params` to handle None values. - Update tests for RFC 2231 continuation sorting.
1 parent d610f11 commit bcb6b45

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

Lib/email/utils.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,8 +417,14 @@ def decode_params(params):
417417
for name, continuations in rfc2231_params.items():
418418
value = []
419419
extended = False
420-
# Sort by number
421-
continuations.sort()
420+
# Sort by number, treating None as 0 if there is no 0,
421+
# and ignore it if there is already a 0.
422+
has_zero = any(x[0] == 0 for x in continuations)
423+
if has_zero:
424+
continuations = [x for x in continuations if x[0] is not None]
425+
else:
426+
continuations = [(x[0] or 0, x[1], x[2]) for x in continuations]
427+
continuations.sort(key=lambda x: x[0])
422428
# And now append all values in numerical order, converting
423429
# %-encodings for the encoded segments. If any of the
424430
# continuation names ends in a *, then the entire string, after

Lib/test/test_email/test_email.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,24 @@ def test_bad_param(self):
389389
msg = email.message_from_string("Content-Type: blarg; baz; boo\n")
390390
self.assertEqual(msg.get_param('baz'), '')
391391

392+
def test_continuation_sorting_part_order(self):
393+
msg = email.message_from_string(
394+
"Content-Disposition: attachment; "
395+
"filename*=\"ignored\"; "
396+
"filename*0*=\"utf-8''foo%20\"; "
397+
"filename*1*=\"bar.txt\"\n"
398+
)
399+
filename = msg.get_filename()
400+
self.assertEqual(filename, 'foo bar.txt')
401+
402+
def test_sorting_no_continuations(self):
403+
msg = email.message_from_string(
404+
"Content-Disposition: attachment; "
405+
"filename*=\"bar.txt\"; "
406+
)
407+
filename = msg.get_filename()
408+
self.assertEqual(filename, 'bar.txt')
409+
392410
def test_missing_filename(self):
393411
msg = email.message_from_string("From: foo\n")
394412
self.assertEqual(msg.get_filename(), None)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:mod:`email`: Fix :exc:`TypeError` in :func:`email.utils.decode_params`
2+
when sorting :rfc:`2231` continuations that contain an unnumbered section.

0 commit comments

Comments
 (0)