Files
nexarch/mail/docs/ING-04-PRUEFPROTOKOLL.md
sysops dff6b8b7a4 ING-04: mime-anhang-parsing
- 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
2026-08-30 23:31:02 +02:00

3.7 KiB
Raw Permalink Blame History

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.