]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-108280: Give a meaningful error for an invalid imaplib greeting (GH-152768)
authorSerhiy Storchaka <storchaka@gmail.com>
Thu, 2 Jul 2026 07:15:13 +0000 (10:15 +0300)
committerGitHub <noreply@github.com>
Thu, 2 Jul 2026 07:15:13 +0000 (10:15 +0300)
Connecting to a server that does not send a valid IMAP4 greeting, such as
a POP3 server answering on the IMAP port, failed with the unhelpful
"imaplib.IMAP4.error: None".  A meaningful message is now raised instead.

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-12-00-00.gh-issue-108280.Nq8vTr.rst [new file with mode: 0644]

index 26773fb0ee083be528948c69b9c68b20d1c9c174..ca2ae40726b2d1275031ccaa3d9bac77bafb0dd5 100644 (file)
@@ -253,7 +253,11 @@ class IMAP4:
         elif 'OK' in self.untagged_responses:
             self.state = 'NONAUTH'
         else:
-            raise self.error(self.welcome)
+            # A continuation ('+') greeting is returned as None; report its
+            # raw line, still held by the last match (gh-108280).
+            greeting = (self.welcome or self.mo.string).decode(
+                self._encoding, 'replace')
+            raise self.error('invalid greeting: ' + greeting)
 
         self._refresh_capabilities()
         if __debug__:
index fa23d09806e6fb19f93793264b0c33457a2f8446..67bf47ad41a1aceb315a5deafb1e46528713312b 100644 (file)
@@ -331,6 +331,39 @@ class NewIMAPTestsMixin:
         self.assertRaises(imaplib.IMAP4.abort, self.imap_class,
                           *server.server_address)
 
+    def test_invalid_greeting(self):
+        # An invalid greeting, e.g. from a POP3 server on the IMAP port,
+        # must not fail with "error: None" but report the server's line
+        # (gh-108280).
+        class Pop3Handler(socketserver.StreamRequestHandler):
+            def handle(self):
+                self.wfile.write(b'+OK POP3 server ready\r\n')
+        _, server = self._setup(Pop3Handler, connect=False)
+        with self.assertRaisesRegex(imaplib.IMAP4.error,
+                                    r'invalid greeting: \+OK POP3 server ready'):
+            self.imap_class(*server.server_address)
+
+    def test_invalid_greeting_untagged(self):
+        # An untagged greeting that is neither OK nor PREAUTH (e.g. BYE)
+        # is reported as is (gh-108280).
+        class ByeHandler(socketserver.StreamRequestHandler):
+            def handle(self):
+                self.wfile.write(b'* BYE Server unavailable\r\n')
+        _, server = self._setup(ByeHandler, connect=False)
+        with self.assertRaisesRegex(imaplib.IMAP4.error,
+                                    r'invalid greeting: \* BYE Server unavailable'):
+            self.imap_class(*server.server_address)
+
+    def test_invalid_greeting_bare_continuation(self):
+        # A bare continuation greeting is still reported (gh-108280).
+        class BareHandler(socketserver.StreamRequestHandler):
+            def handle(self):
+                self.wfile.write(b'+\r\n')
+        _, server = self._setup(BareHandler, connect=False)
+        with self.assertRaisesRegex(imaplib.IMAP4.error,
+                                    r'invalid greeting: \+'):
+            self.imap_class(*server.server_address)
+
     def test_line_termination(self):
         class BadNewlineHandler(SimpleIMAPHandler):
             def cmd_CAPABILITY(self, tag, args):
diff --git a/Misc/NEWS.d/next/Library/2026-07-01-12-00-00.gh-issue-108280.Nq8vTr.rst b/Misc/NEWS.d/next/Library/2026-07-01-12-00-00.gh-issue-108280.Nq8vTr.rst
new file mode 100644 (file)
index 0000000..487c9da
--- /dev/null
@@ -0,0 +1,4 @@
+Connecting :mod:`imaplib` to a server that does not send a valid IMAP4
+greeting (for example a POP3 server answering on the IMAP port) now raises
+an error reporting the server's response instead of
+``imaplib.IMAP4.error: None``.