- mail/internal/mimeparse.Parse: rekursive Multipart-Zerlegung, Zeichensatz-Reparatur (mime.WordDecoder mit htmlindex-CharsetReader, defensiv statt Abbruch), quoted-printable/base64-Dekodierung - io.LimitReader fuer jeden Anhang (archivmail known-issues #3: Speicherbombe durch io.ReadAll ohne Limit vermieden) - ErrAttachmentTooLarge bei Ueberschreitung - nur Parsing, keine Speicherung (ARC-01s Aufgabe, nicht dupliziert) - 6 Tests + echtes Go-Fuzzing: 728.164 reale Fuzz-Durchlaeufe (go test -fuzz=FuzzParse -fuzztime=45s), 0 Abstuerze, 146 coverage-erweiternde Eingaben gefunden - alle 3 Pflichtpruefungen real bestanden (Speicherbombe abgewehrt, realitaetsnaher Testkorpus, Fuzz-Nachweis) Pruefungen siehe mail/docs/ING-04-PRUEFPROTOKOLL.md
66 lines
3.7 KiB
Markdown
66 lines
3.7 KiB
Markdown
# ING-04 – Prüfprotokoll: MIME- & Anhang-Parsing
|
||
|
||
Keine Vorbedingungen (Wave 1, sofort startbar). ING-04 ist die
|
||
Voraussetzung für ARC-01 (Objekt-Speicher) — nicht nur eine
|
||
Ergänzung, sondern der direkte Blocker (`ARC-01.dependsOn = ["ING-04"]`).
|
||
|
||
## Bekannten Fehler vermieden
|
||
|
||
archivmail (`known-issues-archivmail.md` Punkt 3): Anhänge wurden über
|
||
`io.ReadAll` ohne Größenlimit gelesen — Speicherbombe durch große/
|
||
böswillige Anhänge. Hier läuft JEDER Anhang-Lesevorgang über
|
||
`io.LimitReader(r, maxSize+1)` — eine Überschreitung führt zu
|
||
`ErrAttachmentTooLarge`, nicht zu stillem Abschneiden oder
|
||
unbegrenztem Speicherwachstum.
|
||
|
||
## Umsetzung
|
||
|
||
- `mail/internal/mimeparse.Parse` — zerlegt eine MIME-Nachricht
|
||
vollständig, rekursiv über verschachtelte `multipart/*`-Container.
|
||
- Zeichensatz-Reparatur: `mime.WordDecoder` mit eigenem
|
||
`CharsetReader` (via `golang.org/x/text/encoding/htmlindex`) — ein
|
||
unbekannter/kaputter Zeichensatz reicht den Rohtext unverändert
|
||
durch statt abzubrechen.
|
||
- Content-Transfer-Encoding: `quoted-printable`/`base64` werden
|
||
dekodiert, unbekannte Encodings unverändert durchgereicht (defensiv).
|
||
- **Nur Parsing, keine Speicherung** — Objekt-Speicher ist explizit
|
||
ARC-01s Aufgabe (Ticket-"Nicht Bestandteil"), dieses Paket schreibt
|
||
nirgends in einen Objektspeicher.
|
||
|
||
## Prüfungen
|
||
|
||
| # | Prüfung | Ergebnis |
|
||
|---|---|---|
|
||
| 1 | Test mit sehr großem simuliertem Anhang bestätigt harte Ablehnung statt Speicheranstieg | **bestanden** – `TestParse_OversizedAttachmentRejectedNotMemoryExhausted`: ein UNBEGRENZTER `io.Reader` (liefert endlos Bytes) als Anhang-Body — `Parse` bricht real mit `ErrAttachmentTooLarge` ab, statt (wie ein `io.ReadAll`-basierter Parser) den Prozess durch unbegrenztes Speicherwachstum zum Absturz zu bringen. Test läuft in Millisekunden durch, kein Speicheranstieg |
|
||
| 2 | Testkorpus mit realitätsnahen Multipart-/Encoding-Varianten läuft fehlerfrei durch | **bestanden** – `TestParse_RealisticCorpusRunsCleanly`: 4 realitätsnahe Varianten (einfacher Text, quoted-printable, multipart/alternative, leere Multipart-Hülle mit Präambel/Epilog) laufen alle fehlerfrei durch |
|
||
| 3 | Fuzz-/Grenzwerttest mit kaputten MIME-Strukturen bricht kontrolliert ab, kein Absturz | **bestanden** – `FuzzParse`: ECHTES Go-Fuzzing (`go test -fuzz=FuzzParse -fuzztime=45s`), **728.164 reale Testläufe** mit mutierten/kaputten Byte-Sequenzen, 146 "interessante" (coverage-erweiternde) Eingaben gefunden, KEIN einziger Absturz (jeder `panic` hätte den Test sofort fehlschlagen lassen) |
|
||
|
||
**Zusätzliche Tests (je Akzeptanzkriterium mindestens ein Test):**
|
||
- `TestParse_NestedMultipartFullyDecomposed` (AC1: verschachtelte
|
||
Multipart-Teile vollständig zerlegt — `multipart/mixed` enthält
|
||
`multipart/alternative` UND einen Anhang, alle 3 Blatt-Teile
|
||
gefunden).
|
||
- `TestParse_AttachmentMetadataExtracted` (AC2: Dateiname,
|
||
Content-Type, Größe korrekt extrahiert).
|
||
- `TestParse_BrokenCharsetIsRepairedNotAborted`,
|
||
`TestParse_ISO88591FilenameDecoded` (AC3: kaputter/unbekannter
|
||
Zeichensatz repariert statt Abbruch; RFC-2047-kodierter,
|
||
ISO-8859-1-Dateiname real korrekt zu "Rechnung Ü" dekodiert).
|
||
|
||
## Build/Test-Ergebnis (192.168.1.131)
|
||
|
||
```
|
||
go build ./... -> clean
|
||
go vet ./... -> clean
|
||
golangci-lint run ./... -> 0 issues
|
||
go test ./... -p 1 -> alle Mail-Pakete bestanden (inkl. mimeparse, example, pflichttestgate)
|
||
go test ./internal/mimeparse/... -fuzz=FuzzParse -fuzztime=45s -> PASS, 728.164 Ausführungen, 0 Abstürze
|
||
```
|
||
|
||
## Gesamtergebnis
|
||
|
||
**Bestanden.** Alle drei Akzeptanzkriterien und alle drei
|
||
Pflichtprüfungen real erfüllt, inklusive eines echten, nicht nur
|
||
simulierten Fuzz-Laufs mit über 700.000 Testfällen. Entsperrt ARC-01
|
||
(Objekt-Speicher-Anbindung), IMP-02, ING-10, ARC-10.
|