imaplib2: fix handling of zero-sized IMAP objects

self._expecting_data was used both as the expected data length and the
flag that we expect some data.  This obviously fails when advertized
data length is zero, so self._expecting_data_len was introduced to
hold the length of the expected data and self._expecting_data was left
as the flag that we expect the data to come.

GitHub issue: https://github.com/OfflineIMAP/offlineimap/issues/15
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
This commit is contained in:
Eygene Ryabinkin 2013-08-27 18:56:43 +04:00
parent 95aea5e489
commit d55e4ef15e
2 changed files with 13 additions and 8 deletions

View File

@ -28,6 +28,7 @@ WIP (add new stuff for the next release)
local repository for the account being processed. local repository for the account being processed.
* [regression] pass folder names to the foldersort function, * [regression] pass folder names to the foldersort function,
revert the documented behaviour revert the documented behaviour
* Fix handling of zero-sized IMAP data items (GitHub#15).
OfflineIMAP v6.5.5-rc1 (2012-09-05) OfflineIMAP v6.5.5-rc1 (2012-09-05)
=================================== ===================================

View File

@ -299,7 +299,8 @@ class IMAP4(object):
self.idle_rqb = None # Server IDLE Request - see _IdleCont self.idle_rqb = None # Server IDLE Request - see _IdleCont
self.idle_timeout = None # Must prod server occasionally self.idle_timeout = None # Must prod server occasionally
self._expecting_data = 0 # Expecting message data self._expecting_data = False # Expecting message data
self._expecting_data_len = 0 # How many characters we expect
self._accumulated_data = [] # Message data accumulated so far self._accumulated_data = [] # Message data accumulated so far
self._literal_expected = None # Message data descriptor self._literal_expected = None # Message data descriptor
@ -1463,10 +1464,11 @@ class IMAP4(object):
def _put_response(self, resp): def _put_response(self, resp):
if self._expecting_data > 0: if self._expecting_data:
rlen = len(resp) rlen = len(resp)
dlen = min(self._expecting_data, rlen) dlen = min(self._expecting_data_len, rlen)
self._expecting_data -= dlen self._expecting_data_len -= dlen
self._expecting_data = (self._expecting_data_len != 0)
if rlen <= dlen: if rlen <= dlen:
self._accumulated_data.append(resp) self._accumulated_data.append(resp)
return return
@ -1490,8 +1492,9 @@ class IMAP4(object):
dat = resp dat = resp
if self._match(self.literal_cre, dat): if self._match(self.literal_cre, dat):
self._literal_expected[1] = dat self._literal_expected[1] = dat
self._expecting_data = int(self.mo.group('size')) self._expecting_data = True
if __debug__: self._log(4, 'expecting literal size %s' % self._expecting_data) self._expecting_data_len = int(self.mo.group('size'))
if __debug__: self._log(4, 'expecting literal size %s' % self._expecting_data_len)
return return
typ = self._literal_expected[0] typ = self._literal_expected[0]
self._literal_expected = None self._literal_expected = None
@ -1537,8 +1540,9 @@ class IMAP4(object):
# Is there a literal to come? # Is there a literal to come?
if self._match(self.literal_cre, dat): if self._match(self.literal_cre, dat):
self._expecting_data = int(self.mo.group('size')) self._expecting_data = True
if __debug__: self._log(4, 'read literal size %s' % self._expecting_data) self._expecting_data_len = int(self.mo.group('size'))
if __debug__: self._log(4, 'read literal size %s' % self._expecting_data_len)
self._literal_expected = [typ, dat] self._literal_expected = [typ, dat]
return return