diff options
| author | Guilhem Moulin <guilhem@fripost.org> | 2016-03-11 22:04:17 +0100 | 
|---|---|---|
| committer | Guilhem Moulin <guilhem@fripost.org> | 2016-03-12 00:48:39 +0100 | 
| commit | 5570af137725259a66043bcb747ecbdb3839a2d3 (patch) | |
| tree | 6d3eced2368c0b5fbeb92d6adf27d8998f04ece1 /lib | |
| parent | f7becde978ab43cc5859a89d82aeb69521967a2d (diff) | |
Net::IMAP::InterIMAP: Don't increase UIDNEXT when receiving EXISTS responses.
Indeed, if the server sends
    * n EXISTS
    * n EXPUNGE
meaning a new message is received, and is immediately removed
afterwards, the server might have allocated a new UID for the removed
message.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Net/IMAP/InterIMAP.pm | 18 | 
1 files changed, 12 insertions, 6 deletions
diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm index be61cb6..cdc5697 100644 --- a/lib/Net/IMAP/InterIMAP.pm +++ b/lib/Net/IMAP/InterIMAP.pm @@ -645,6 +645,7 @@ sub unselect($) {      # we'll get back to it      $self->{_VANISHED} = [];      $self->{_MODIFIED} = {}; +    $self->{_NEW} = 0;  } @@ -1082,6 +1083,7 @@ sub get_cache($@) {  #   persistent cache's values.  sub is_dirty($$) {      my ($self, $mailbox) = @_; +    return 1 if $self->{_NEW};      $self->_updated_cache($mailbox, qw/HIGHESTMODSEQ UIDNEXT/);  } @@ -1091,6 +1093,7 @@ sub is_dirty($$) {  #   internal cache's UIDNEXT value differs from its persistent cache's.  sub has_new_mails($$) {      my ($self, $mailbox) = @_; +    return 1 if $self->{_NEW};      $self->_updated_cache($mailbox, 'UIDNEXT');  } @@ -1181,6 +1184,7 @@ sub pull_new_messages($$&@) {      my @ignore = sort { $a <=> $b } @_;      my $mailbox = $self->{_SELECTED} // $self->panic(); +    my $cache = $self->{_CACHE}->{$mailbox};      my $UIDNEXT;      do { @@ -1205,19 +1209,20 @@ sub pull_new_messages($$&@) {          # 2^32-1: don't use '*' since the highest UID can be known already          $range .= "$since:4294967295"; -        $UIDNEXT = $self->{_CACHE}->{$mailbox}->{UIDNEXT} // $self->panic(); # sanity check +        $UIDNEXT = $cache->{UIDNEXT} // $self->panic(); # sanity check          $self->_send("UID FETCH $range ($attrs)", sub($) {              my $mail = shift;              $UIDNEXT = $mail->{UID} + 1 if $UIDNEXT <= $mail->{UID};              $callback->($mail) if defined $callback; -        }) if $first < $UIDNEXT; +        }) if $first < $UIDNEXT or $self->{_NEW};          # update the persistent cache for UIDNEXT (not for HIGHESTMODSEQ          # since there might be pending updates)          $self->set_cache($mailbox, UIDNEXT => $UIDNEXT); +        $self->{_NEW} = 0;      }      # loop if new messages were received in the meantime -    while ($UIDNEXT < $self->{_CACHE}->{$mailbox}->{UIDNEXT}); +    while ($self->{_NEW} or $UIDNEXT < $cache->{UIDNEXT});  } @@ -1993,6 +1998,7 @@ sub _open_mailbox($$) {      # we'll get back to it      $self->{_VANISHED} = [];      $self->{_MODIFIED} = {}; +    $self->{_NEW} = 0;      $self->{_SELECTED} = $mailbox;      $self->{_CACHE}->{$mailbox} //= {}; @@ -2233,12 +2239,12 @@ sub _resp($$;&$$) {              # /!\ $cache->{EXISTS} MUST NOT be defined on SELECT              if (defined $cache->{EXISTS}) {                  $self->panic("Unexpected EXISTS shrink $1 < $cache->{EXISTS}!") if $1 < $cache->{EXISTS}; -                # the actual UIDNEXT is *at least* that -                $cache->{UIDNEXT} += $1 - $cache->{EXISTS} if defined $cache->{UIDNEXT}; +                $self->{_NEW} += $1 - $cache->{EXISTS} if $1 > $cache->{EXISTS}; # new mails              }              $cache->{EXISTS} = $1;          }          elsif (/\A([0-9]+) EXPUNGE\z/) { +            $self->panic() unless defined $cache->{EXISTS}; # sanity check              # /!\ No bookkeeping since there is no internal cache mapping sequence numbers to UIDs              if ($self->_enabled('QRESYNC')) {                  $self->panic("$1 <= $cache->{EXISTS}") if $1 <= $cache->{EXISTS}; # sanity check @@ -2270,7 +2276,7 @@ sub _resp($$;&$$) {              $callback->($mailbox, %status) if defined $callback and $cmd eq 'STATUS';          }          elsif (s/\A([0-9]+) FETCH \(//) { -            $self->panic("$1 <= $cache->{EXISTS}") unless $1 <= $cache->{EXISTS}; # sanity check +            $cache->{EXISTS} = $1 if $1 > $cache->{EXISTS};              my ($seq, $first) = ($1, 1);              my %mail;              while ($_ ne ')') {  | 
