Skip to content

Commit 2ea02f9

Browse files
committed
eliminate quadratic time complexity when counting
1 parent d356a14 commit 2ea02f9

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

Lib/email/message.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,19 @@ def _parseparam(s):
7878
while s.find(';', start) == start:
7979
start += 1
8080
end = s.find(';', start)
81-
while end > 0 and (
82-
s.count('"', start, end) - s.count('\\"', start, end)
83-
) % 2:
84-
end = s.find(';', end + 1)
81+
# The following while block is equivalent to:
82+
#
83+
# while end > 0 and (
84+
# s.count('"', start, end) - s.count('\\"', start, end)
85+
# ) % 2:
86+
# end = s.find(';', end + 1)
87+
#
88+
ind, diff = start, 0
89+
while end > 0:
90+
diff += s.count('"', ind, end) - s.count('\\"', ind, end)
91+
if diff % 2 == 0:
92+
break
93+
end, ind = ind, s.find(';', end + 1)
8594
if end < 0:
8695
end = len(s)
8796
i = s.find('=', start, end)

Lib/test/test_email/test_email.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,11 @@ def test_get_param_linear_complexity(self):
497497
self.assertEqual(len(set(res)), 1)
498498
self.assertEqual(res[0], r)
499499

500+
# This will be considered as a single parameter.
501+
malformed = 's="' + ';' * (N - 1)
502+
res = email.message._parseparam(malformed)
503+
self.assertEqual(res, [malformed])
504+
500505
def test_field_containment(self):
501506
msg = email.message_from_string('Header: exists')
502507
self.assertIn('header', msg)

0 commit comments

Comments
 (0)