mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-11 05:06:51 +00:00
GODT-1152: Correctly resolve wildcard sequence/UID set
This commit is contained in:
committed by
Jakub Cuth
parent
323303a98b
commit
27cfda680d
@ -526,18 +526,6 @@ func (im *imapMailbox) listMessages(isUID bool, seqSet *imap.SeqSet, items []ima
|
||||
return err
|
||||
}
|
||||
|
||||
// From RFC: UID range of 559:* always includes the UID of the last message
|
||||
// in the mailbox, even if 559 is higher than any assigned UID value.
|
||||
// See: https://tools.ietf.org/html/rfc3501#page-61
|
||||
if isUID && seqSet.Dynamic() && len(apiIDs) == 0 {
|
||||
l.Debug("Requesting empty UID dynamic fetch, adding latest message")
|
||||
apiID, err := im.storeMailbox.GetLatestAPIID()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
apiIDs = []string{apiID}
|
||||
}
|
||||
|
||||
input := make([]interface{}, len(apiIDs))
|
||||
for i, apiID := range apiIDs {
|
||||
input[i] = apiID
|
||||
|
||||
@ -36,23 +36,36 @@ import (
|
||||
func (storeMailbox *Mailbox) GetAPIIDsFromUIDRange(start, stop uint32) (apiIDs []string, err error) {
|
||||
err = storeMailbox.db().View(func(tx *bolt.Tx) error {
|
||||
b := storeMailbox.txGetIMAPIDsBucket(tx)
|
||||
c := b.Cursor()
|
||||
|
||||
// If the start range is a wildcard, the range can only refer to the last message in the mailbox.
|
||||
if start == 0 {
|
||||
_, apiID := c.Last()
|
||||
apiIDs = append(apiIDs, string(apiID))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Resolve the stop value to be the final UID in the mailbox.
|
||||
if stop == 0 {
|
||||
// A null stop means no stop.
|
||||
stop = ^uint32(0)
|
||||
stop = storeMailbox.txGetFinalUID(b)
|
||||
}
|
||||
|
||||
// After resolving the stop value, it might be less than start so we sort it.
|
||||
if start > stop {
|
||||
start, stop = stop, start
|
||||
}
|
||||
|
||||
startb := itob(start)
|
||||
stopb := itob(stop)
|
||||
|
||||
c := b.Cursor()
|
||||
for k, v := c.Seek(startb); k != nil && bytes.Compare(k, stopb) <= 0; k, v = c.Next() {
|
||||
apiIDs = append(apiIDs, string(v))
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
return
|
||||
|
||||
return apiIDs, err
|
||||
}
|
||||
|
||||
// GetAPIIDsFromSequenceRange returns API IDs by IMAP sequence number range.
|
||||
@ -60,28 +73,47 @@ func (storeMailbox *Mailbox) GetAPIIDsFromSequenceRange(start, stop uint32) (api
|
||||
err = storeMailbox.db().View(func(tx *bolt.Tx) error {
|
||||
b := storeMailbox.txGetIMAPIDsBucket(tx)
|
||||
c := b.Cursor()
|
||||
|
||||
// If the start range is a wildcard, the range can only refer to the last message in the mailbox.
|
||||
if start == 0 {
|
||||
_, apiID := c.Last()
|
||||
apiIDs = append(apiIDs, string(apiID))
|
||||
return nil
|
||||
}
|
||||
|
||||
var i uint32
|
||||
|
||||
for k, v := c.First(); k != nil; k, v = c.Next() {
|
||||
i++
|
||||
|
||||
if i < start {
|
||||
continue
|
||||
}
|
||||
|
||||
if stop > 0 && i > stop {
|
||||
break
|
||||
}
|
||||
|
||||
apiIDs = append(apiIDs, string(v))
|
||||
}
|
||||
|
||||
if stop == 0 && len(apiIDs) == 0 {
|
||||
if _, apiID := c.Last(); len(apiID) > 0 {
|
||||
apiIDs = append(apiIDs, string(apiID))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
return
|
||||
|
||||
return apiIDs, err
|
||||
}
|
||||
|
||||
// GetLatestAPIID returns the latest message API ID which still exists.
|
||||
// Info: not the latest IMAP UID which can be already removed.
|
||||
func (storeMailbox *Mailbox) GetLatestAPIID() (apiID string, err error) {
|
||||
err = storeMailbox.db().View(func(tx *bolt.Tx) error {
|
||||
b := storeMailbox.txGetAPIIDsBucket(tx)
|
||||
c := b.Cursor()
|
||||
c := storeMailbox.txGetAPIIDsBucket(tx).Cursor()
|
||||
lastAPIID, _ := c.Last()
|
||||
apiID = string(lastAPIID)
|
||||
if apiID == "" {
|
||||
@ -283,3 +315,8 @@ func (storeMailbox *Mailbox) GetUIDByHeader(header *mail.Header) (foundUID uint3
|
||||
|
||||
return foundUID
|
||||
}
|
||||
|
||||
func (storeMailbox *Mailbox) txGetFinalUID(b *bolt.Bucket) uint32 {
|
||||
uid, _ := b.Cursor().Last()
|
||||
return btoi(uid)
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ func checkMailboxMessageIDs(t *testing.T, m *mocksForStore, mailboxLabel string,
|
||||
storeAddress := m.store.addresses[addrID1]
|
||||
storeMailbox := storeAddress.mailboxes[mailboxLabel]
|
||||
|
||||
ids, err := storeMailbox.GetAPIIDsFromSequenceRange(0, uint32(len(wantIDs)))
|
||||
ids, err := storeMailbox.GetAPIIDsFromSequenceRange(1, uint32(len(wantIDs)))
|
||||
require.Nil(t, err)
|
||||
|
||||
idx := 0
|
||||
|
||||
Reference in New Issue
Block a user