]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-88574: Skip a spurious blank line after a literal in imaplib (GH-152751...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Thu, 2 Jul 2026 13:20:36 +0000 (15:20 +0200)
committerGitHub <noreply@github.com>
Thu, 2 Jul 2026 13:20:36 +0000 (13:20 +0000)
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 53ff1a28ccfa69925c3c452cfc003970640fa65b)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lib/imaplib.py
Lib/test/test_imaplib.py
Misc/NEWS.d/next/Library/2026-07-01-10-00-00.gh-issue-88574.Kz3wQm.rst [new file with mode: 0644]

index 0bdb9ff047ba7bb9ce6ea006320d0151dc06d66d..2041a083f0bc0e260815dad0fd956dd3d80d1a12 100644 (file)
@@ -1286,6 +1286,10 @@ class IMAP4:
 
                 dat = self._get_line()
 
+                # Skip a blank line that some servers send after a literal.
+                if dat == b'':
+                    dat = self._get_line()
+
             self._append_untagged(typ, dat)
 
         # Bracketed response information?
index b5a7950fe4e067d2458e5feacd3ae48333c59ca7..f0875d39397b609a247a53ff4355c3757c9bb99e 100644 (file)
@@ -855,6 +855,23 @@ class NewIMAPTestsMixin:
         self.assertEqual(typ, 'OK')
         self.assertEqual(server.args, ['~/Mail/', '%'])
 
+    def test_extra_blank_line_after_literal(self):
+        # Some buggy servers send an extra blank line after the counted
+        # literal data.  imaplib should skip it instead of failing.
+        class BlankLineHandler(SimpleIMAPHandler):
+            def cmd_FETCH(self, tag, args):
+                self._send(b'* 1 FETCH (BODY[HEADER] {13}\r\n')
+                self._send(b'Subject: test')       # 13-byte literal
+                self._send(b'\r\n)\r\n')            # stray blank line, then ')'
+                self._send_tagged(tag, 'OK', 'FETCH completed')
+        client, _ = self._setup(BlankLineHandler)
+        client.login('user', 'pass')
+        client.select()
+        typ, data = client.fetch('1', '(BODY[HEADER])')
+        self.assertEqual(typ, 'OK')
+        self.assertEqual(data, [(b'1 (BODY[HEADER] {13}', b'Subject: test'),
+                                b')'])
+
     def test_unselect(self):
         client, server = self._setup(SimpleIMAPHandler)
         client.login('user', 'pass')
diff --git a/Misc/NEWS.d/next/Library/2026-07-01-10-00-00.gh-issue-88574.Kz3wQm.rst b/Misc/NEWS.d/next/Library/2026-07-01-10-00-00.gh-issue-88574.Kz3wQm.rst
new file mode 100644 (file)
index 0000000..8d95bbb
--- /dev/null
@@ -0,0 +1,2 @@
+:mod:`imaplib` no longer fails when a server sends a spurious blank line
+after the counted data of a literal.  Such a blank line is now skipped.