diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-04-15 16:23:20 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-15 16:23:20 (GMT) |
commit | 74125a60b7a477451ff2b8385bfbce3fdaee8dbc (patch) | |
tree | 2a6670b9046ee35a4dc19d907b862c158c33dbfe /Lib/imaplib.py | |
parent | 0810fa79885276114d1a94e2ce61da367ebb1ffc (diff) | |
download | cpython-74125a60b7a477451ff2b8385bfbce3fdaee8dbc.zip cpython-74125a60b7a477451ff2b8385bfbce3fdaee8dbc.tar.gz cpython-74125a60b7a477451ff2b8385bfbce3fdaee8dbc.tar.bz2 |
bpo-36348: IMAP4.logout() doesn't ignore exc (GH-12411)
The imap.IMAP4.logout() method no longer ignores silently arbitrary
exceptions.
Changes:
* The IMAP4.logout() method now expects a "BYE" untagged response,
rather than relying on _check_bye() which raises a self.abort()
exception.
* IMAP4.__exit__() now does nothing if the client already logged out.
* Add more debug info if test_logout() tests fail.
Diffstat (limited to 'Lib/imaplib.py')
-rw-r--r-- | Lib/imaplib.py | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/Lib/imaplib.py b/Lib/imaplib.py index dd237f7..341ee25 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -272,6 +272,9 @@ class IMAP4: return self def __exit__(self, *args): + if self.state == "LOGOUT": + return + try: self.logout() except OSError: @@ -625,11 +628,8 @@ class IMAP4: Returns server 'BYE' response. """ self.state = 'LOGOUT' - try: typ, dat = self._simple_command('LOGOUT') - except: typ, dat = 'NO', ['%s: %s' % sys.exc_info()[:2]] + typ, dat = self._simple_command('LOGOUT') self.shutdown() - if 'BYE' in self.untagged_responses: - return 'BYE', self.untagged_responses['BYE'] return typ, dat @@ -1012,16 +1012,17 @@ class IMAP4: def _command_complete(self, name, tag): + logout = (name == 'LOGOUT') # BYE is expected after LOGOUT - if name != 'LOGOUT': + if not logout: self._check_bye() try: - typ, data = self._get_tagged_response(tag) + typ, data = self._get_tagged_response(tag, expect_bye=logout) except self.abort as val: raise self.abort('command: %s => %s' % (name, val)) except self.error as val: raise self.error('command: %s => %s' % (name, val)) - if name != 'LOGOUT': + if not logout: self._check_bye() if typ == 'BAD': raise self.error('%s command error: %s %s' % (name, typ, data)) @@ -1117,7 +1118,7 @@ class IMAP4: return resp - def _get_tagged_response(self, tag): + def _get_tagged_response(self, tag, expect_bye=False): while 1: result = self.tagged_commands[tag] @@ -1125,9 +1126,15 @@ class IMAP4: del self.tagged_commands[tag] return result + if expect_bye: + typ = 'BYE' + bye = self.untagged_responses.pop(typ, None) + if bye is not None: + # Server replies to the "LOGOUT" command with "BYE" + return (typ, bye) + # If we've seen a BYE at this point, the socket will be # closed, so report the BYE now. - self._check_bye() # Some have reported "unexpected response" exceptions. |