90 lines
3.9 KiB
Markdown
90 lines
3.9 KiB
Markdown
# 🔴 KRITISCH — mbox-Leser liefert falsche Mails (Buffer-Aliasing)
|
|
|
|
**Schweregrad: hoch.** Der Leser gibt fuer fast jeden Index dieselbe (falsche)
|
|
Mail zurueck. Betrifft Vorschau, manuelles Verschieben, Archiv-Export und
|
|
Archiv-Dedup.
|
|
|
|
**Entwarnung vorweg:** Die **Archiv-Dateien auf der Platte sind korrekt.** Der
|
|
Schreiber ist ein anderer Pfad und haengt die Rohbytes richtig an. Geprueft:
|
|
In `colak@dr-gold.de/INBOX.mbox` steht an Position 537 exakt das, was
|
|
`mbox_index` sagt. **Kaputt ist ausschliesslich der Leser.** Es sind keine Daten
|
|
verloren.
|
|
|
|
## Die Ursache — eine Zeile
|
|
|
|
[`backend/06-mbox.go:441`](backend/06-mbox.go), `readMboxMessagesBytes`:
|
|
|
|
```go
|
|
if inMsg && cur.Len() > 0 {
|
|
msgs = append(msgs, bytes.TrimRight(cur.Bytes(), "\n")) // Slice ZEIGT IN cur's Puffer
|
|
cur.Reset() // Puffer wird wiederverwendet
|
|
}
|
|
```
|
|
|
|
`bytes.Buffer.Bytes()` liefert **keine Kopie**, sondern einen Slice **in den
|
|
internen Puffer**. Direkt danach `cur.Reset()` — der Puffer wird fuer die
|
|
naechste Mail ueberschrieben. **Alle zuvor angehaengten Slices zeigen auf
|
|
denselben Speicher** und tragen am Ende den zuletzt geschriebenen Inhalt.
|
|
|
|
Der Lehrbuchfehler „`Buffer.Bytes()` + `Reset()` ohne Kopie".
|
|
|
|
## Der Fix
|
|
|
|
```go
|
|
if inMsg && cur.Len() > 0 {
|
|
trimmed := bytes.TrimRight(cur.Bytes(), "\n")
|
|
msg := make([]byte, len(trimmed))
|
|
copy(msg, trimmed) // <-- ECHTE Kopie
|
|
msgs = append(msgs, msg)
|
|
cur.Reset()
|
|
}
|
|
```
|
|
(Dasselbe fuer den Abschluss nach der Schleife, falls dort ebenfalls
|
|
`cur.Bytes()` ohne Kopie angehaengt wird — bitte pruefen.)
|
|
|
|
**Besser noch:** `bytes.Buffer` ganz vermeiden und die Nachrichten ueber
|
|
Byte-Offsets aus dem Original-Slice schneiden (`b[start:end]`) — dann gibt es
|
|
kein Aliasing-Risiko und keine Kopie zu viel.
|
|
|
|
## Reproduktion (gemessen an `colak@dr-gold.de` / INBOX, 678 Mails)
|
|
|
|
```
|
|
idx | mbox_index sagt | Vorschau liefert
|
|
0 | Katalogseite | Angebot: CARRYMATE Transportgriffe FALSCH
|
|
1 | Angebot: CARRYMATE Transportgriffe | Baustoff + Metall FALSCH
|
|
2 | Schoenes Wochenende | Baustoff + Metall FALSCH
|
|
3 | Bestellung '150129' | Baustoff + Metall FALSCH
|
|
...
|
|
15 | Per E-Mail senden: Bestellschein.doc| Baustoff + Metall FALSCH
|
|
```
|
|
Ab Index 1 kommt **immer dieselbe** Mail zurueck. Die **Liste** und
|
|
`mbox_index` stimmen ueberein — nur der Leser luegt.
|
|
|
|
## Blast Radius — bitte alle pruefen
|
|
|
|
`ReadMboxMessage` / `readMboxMessages` haengen an:
|
|
|
|
| Stelle | Wirkung des Bugs |
|
|
|---|---|
|
|
| `08-viewer.go:51` | **Vorschau** zeigt die falsche Mail |
|
|
| `08-viewer.go:83`, `:335` | dito (Ziel-/Transfer-Vorschau) |
|
|
| **`08-viewer.go:489`** | **manuelles Verschieben** → schreibt die **falsche Mail** in ein echtes Ziel-Postfach |
|
|
| `08-viewer.go:599` | Suche liefert falsche Treffer |
|
|
| `00-router.go:1320` | Transfer-Vorschau |
|
|
| **`12-archive-tools.go:291`, `:332`** | **Archiv-Export** (ZIP) und **Archiv-Dedup** → Export koennte falsche Mails enthalten, Dedup koennte **die falschen loeschen** |
|
|
|
|
**Wichtig:** Falls `/archives/dedup` oder das manuelle Verschieben schon benutzt
|
|
wurden, muss geprueft werden, ob dabei Schaden entstanden ist.
|
|
|
|
## Abnahme
|
|
|
|
1. Unit-Test, der genau das faengt: mbox mit **3 unterschiedlich langen** Mails
|
|
schreiben, dann `readMboxMessagesBytes` aufrufen und pruefen, dass
|
|
`msgs[0] != msgs[1] != msgs[2]` und jede den **erwarteten Betreff** hat.
|
|
(Ein Test mit gleich langen Mails wuerde den Bug NICHT finden — deshalb
|
|
unterschiedliche Laengen, damit der Puffer waechst.)
|
|
2. Live: `/view?account=colak@dr-gold.de&folder=INBOX`, dann fuer die Indizes
|
|
0, 1, 2, 300, 677 die Vorschau abrufen → Betreff und Datum muessen **exakt**
|
|
dem entsprechen, was `mbox_index` fuer diese `seq` sagt.
|
|
3. Ich (Claude) fahre den Sweep ueber alle 678 Indizes von colak gegen
|
|
`mbox_index` — **0 Abweichungen** ist die Latte.
|