Sitelet https://github.com/python/cpython/commit/45bf773f605bdee3b4f8334a97d6130a75b9286a
Skip to content

Commit 45bf773

Browse files
committed
#1555570: correctly handle a \r\n that is split by the read buffer.
Patch and test by Tony Nelson.
1 parent cbe1a4e commit 45bf773

3 files changed

Lines changed: 40 additions & 0 deletions

File tree

‎Lib/email/feedparser.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ def push(self, data):
104104
# data after the final RE. In the case of a NL/CR terminated string,
105105
# this is the empty string.
106106
self._partial = parts.pop()
107+
#GAN 29Mar09 bugs 1555570, 1721862 Confusion at 8K boundary ending with \r:
108+
# is there a \n to follow later?
109+
if not self._partial and parts and parts[-1].endswith('\r'):
110+
self._partial = parts.pop(-2)+parts.pop()
107111
# parts is a list of strings, alternating between the line contents
108112
# and the eol character(s). Gather up a list of lines after
109113
# re-attaching the newlines.

‎Lib/email/test/test_email.py‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2454,6 +2454,39 @@ def test_typed_subpart_iterator_default_type(self):
24542454
-Me
24552455
""")
24562456

2457+
def test_pushCR_LF(self):
2458+
'''FeedParser BufferedSubFile.push() assumed it received complete
2459+
line endings. A CR ending one push() followed by a LF starting
2460+
the next push() added an empty line.
2461+
'''
2462+
imt = [
2463+
("a\r \n", 2),
2464+
("b", 0),
2465+
("c\n", 1),
2466+
("", 0),
2467+
("d\r\n", 1),
2468+
("e\r", 0),
2469+
("\nf", 1),
2470+
("\r\n", 1),
2471+
]
2472+
from email.feedparser import BufferedSubFile, NeedMoreData
2473+
bsf = BufferedSubFile()
2474+
om = []
2475+
nt = 0
2476+
for il, n in imt:
2477+
bsf.push(il)
2478+
nt += n
2479+
n1 = 0
2480+
while True:
2481+
ol = bsf.readline()
2482+
if ol == NeedMoreData:
2483+
break
2484+
om.append(ol)
2485+
n1 += 1
2486+
self.assertTrue(n == n1)
2487+
self.assertTrue(len(om) == nt)
2488+
self.assertTrue(''.join([il for il, n in imt]) == ''.join(om))
2489+
24572490

24582491

24592492
class TestParsers(TestEmailBase):

‎Misc/NEWS‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,9 @@ C-API
473473
Library
474474
-------
475475

476+
- Issue #1555570: email no longer inserts extra blank lines when a \r\n
477+
combo crosses an 8192 byte boundary.
478+
476479
- Issue #9243: Fix sndhdr module and add unit tests, contributed by James Lee.
477480

478481
- ``ast.literal_eval()`` now allows byte literals.

0 commit comments

Comments
 (0)