Skip to content

Commit 9045939

Browse files
serhiy-storchakaclaude
authored andcommitted
gh-88574: Skip a spurious blank line after a literal in imaplib (GH-152751)
Some IMAP servers send an extra blank line after the data of a literal. imaplib mistook it for the response trailer and failed on the next command. Such a blank line is now skipped. (cherry picked from commit 53ff1a2) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent c98e263 commit 9045939

3 files changed

Lines changed: 23 additions & 0 deletions

File tree

Lib/imaplib.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,6 +1286,10 @@ def _get_response(self, start_timeout=False):
12861286

12871287
dat = self._get_line()
12881288

1289+
# Skip a blank line that some servers send after a literal.
1290+
if dat == b'':
1291+
dat = self._get_line()
1292+
12891293
self._append_untagged(typ, dat)
12901294

12911295
# Bracketed response information?

Lib/test/test_imaplib.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,23 @@ def test_lsub(self):
855855
self.assertEqual(typ, 'OK')
856856
self.assertEqual(server.args, ['~/Mail/', '%'])
857857

858+
def test_extra_blank_line_after_literal(self):
859+
# Some buggy servers send an extra blank line after the counted
860+
# literal data. imaplib should skip it instead of failing.
861+
class BlankLineHandler(SimpleIMAPHandler):
862+
def cmd_FETCH(self, tag, args):
863+
self._send(b'* 1 FETCH (BODY[HEADER] {13}\r\n')
864+
self._send(b'Subject: test') # 13-byte literal
865+
self._send(b'\r\n)\r\n') # stray blank line, then ')'
866+
self._send_tagged(tag, 'OK', 'FETCH completed')
867+
client, _ = self._setup(BlankLineHandler)
868+
client.login('user', 'pass')
869+
client.select()
870+
typ, data = client.fetch('1', '(BODY[HEADER])')
871+
self.assertEqual(typ, 'OK')
872+
self.assertEqual(data, [(b'1 (BODY[HEADER] {13}', b'Subject: test'),
873+
b')'])
874+
858875
def test_unselect(self):
859876
client, server = self._setup(SimpleIMAPHandler)
860877
client.login('user', 'pass')
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:mod:`imaplib` no longer fails when a server sends a spurious blank line
2+
after the counted data of a literal. Such a blank line is now skipped.

0 commit comments

Comments
 (0)