fix(PROJ-86): defensive UID-Filterung gegen kaputten IMAP-Server (Sync-Loop)
q.sysops.de (Konto patrick@sysops.de) beantwortet "UID SEARCH UID N:*" auf Mailboxen mit weniger Nachrichten als N fehlerhaft und liefert die letzte existierende UID statt eines leeren Ergebnisses zurück (verifiziert per Debug-Client: "UID SEARCH UID 22:*" auf 21-Nachrichten-Mailbox -> [21]). Ohne Filterung wurde dieselbe UID bei jedem 5-Minuten-Sync erneut als "neu" behandelt und re-indexiert - dabei driftete auch date_ts bei Mails ohne Date-Header ständig auf "jetzt". Server-Antwort wird jetzt client-seitig re-gefiltert, nur UIDs >= angefragtem Minimum zählen als neu. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UPFC6Jk2ke1Pq9XcuVGP1R
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
160b28099e
commit
ffdfa585cc
@@ -398,7 +398,17 @@ func (s *Scheduler) syncFolder(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, fmt.Errorf("imap scheduler: uid search incremental %q: %w", folder, err)
|
return 0, 0, fmt.Errorf("imap scheduler: uid search incremental %q: %w", folder, err)
|
||||||
}
|
}
|
||||||
uids = searchData.AllUIDs()
|
// Defensive re-filter: some IMAP servers mishandle open-ended "N:*"
|
||||||
|
// UID ranges and return UIDs below N anyway (observed against
|
||||||
|
// q.sysops.de — "UID SEARCH UID 22:*" on a 21-message mailbox
|
||||||
|
// returned [21] instead of an empty set). Trusting that blindly
|
||||||
|
// makes the sync loop rediscover the same top message as "new"
|
||||||
|
// forever, every cycle. Never trust the server's range filtering.
|
||||||
|
for _, uid := range searchData.AllUIDs() {
|
||||||
|
if uid >= minUID {
|
||||||
|
uids = append(uids, uid)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// First sync or post-UIDVALIDITY-reset: fetch everything.
|
// First sync or post-UIDVALIDITY-reset: fetch everything.
|
||||||
searchData, err := c.UIDSearch(&imapv2.SearchCriteria{}, nil).Wait()
|
searchData, err := c.UIDSearch(&imapv2.SearchCriteria{}, nil).Wait()
|
||||||
|
|||||||
Reference in New Issue
Block a user