From d26aaefe973dc22926dc8857e9ce7ca86dd2306d Mon Sep 17 00:00:00 2001 From: Menno Finlay-Smits Date: Sat, 2 Dec 2023 09:18:08 +1300 Subject: [PATCH] Don't assume capabilities have been cached when sending literals _send_literal was assuming that _cached_capabilites was populated when checking for LITERAL+ but this isn't guaranteed. has_capability is now used to check for LITERAL+. This will populate the capabilities cache if it hasn't been already. Fixes #560 --- imapclient/imapclient.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/imapclient/imapclient.py b/imapclient/imapclient.py index eea281a8..4025b5aa 100644 --- a/imapclient/imapclient.py +++ b/imapclient/imapclient.py @@ -1675,6 +1675,10 @@ def _raw_command(self, command, args, uid=True): """ command = command.upper() + # Check for LITERAL+ now because if capabilities haven't been cached + # yet, we can't call CAPABILITY while sending another command. + has_literal_plus = self.has_capability("LITERAL+") + if isinstance(args, tuple): args = list(args) if not isinstance(args, list): @@ -1702,7 +1706,7 @@ def _raw_command(self, command, args, uid=True): # Now send the (unquoted) literal if isinstance(item, _quoted): item = item.original - self._send_literal(tag, item) + self._send_literal(tag, item, has_literal_plus) if not is_last: self._imap.send(b" ") else: @@ -1717,9 +1721,9 @@ def _raw_command(self, command, args, uid=True): return self._imap._command_complete(to_unicode(command), tag) - def _send_literal(self, tag, item): + def _send_literal(self, tag, item, has_literal_plus): """Send a single literal for the command with *tag*.""" - if b"LITERAL+" in self._cached_capabilities: + if has_literal_plus: out = b" {" + str(len(item)).encode("ascii") + b"+}\r\n" + item logger.debug("> %s", debug_trunc(out, 64)) self._imap.send(out)