package mailparser import ( "strings" "testing" ) func TestRepairUTF8(t *testing.T) { tests := []struct { name string in string want string }{ {"pure ascii untouched", "Passwort geaendert", "Passwort geaendert"}, {"valid utf8 untouched", "Passwort geändert – ok", "Passwort geändert – ok"}, {"windows1252 umlauts", "Passwort ge\xe4ndert", "Passwort geändert"}, {"windows1252 sharp s", "Mini-Fu\xdfball", "Mini-Fußball"}, {"cp1252 en dash 0x96", "Netbook f\xfcr 207 Euro \x96 jetzt", "Netbook für 207 Euro – jetzt"}, {"cp1252 registered 0xae", "NVIDIA\xae Karten", "NVIDIA® Karten"}, {"mixed valid utf8 and latin1", "Gr\xfc\xdfe – ünd", "Grüße – ünd"}, {"empty", "", ""}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { if got := RepairUTF8(tc.in); got != tc.want { t.Errorf("RepairUTF8(%q) = %q, want %q", tc.in, got, tc.want) } }) } } func TestNeedsCharsetRepair(t *testing.T) { if NeedsCharsetRepair("Passwort geändert") { t.Error("valid UTF-8 must not be flagged for repair") } if !NeedsCharsetRepair("Passwort ge\xe4ndert") { t.Error("raw Latin-1 byte must be flagged for repair") } } // A Subject header with raw 8-bit bytes and no RFC 2047 encoded-word must be // decoded via the Windows-1252 fallback instead of ending up as invalid UTF-8. func TestParseRawEightBitSubject(t *testing.T) { raw := "From: a@example.com\r\n" + "Subject: Passwort f\xfcr WoltLab ge\xe4ndert\r\n" + "Content-Type: text/plain\r\n\r\n" + "Gr\xfc\xdfe\r\n" pm, err := Parse([]byte(raw)) if err != nil { t.Fatalf("Parse: %v", err) } if pm.Subject != "Passwort für WoltLab geändert" { t.Errorf("Subject = %q", pm.Subject) } if !strings.Contains(pm.TextBody, "Grüße") { t.Errorf("TextBody = %q", pm.TextBody) } } // A correctly encoded UTF-8 mail must survive the repair unchanged. func TestParseValidUTF8NotMangled(t *testing.T) { raw := "From: a@example.com\r\n" + "Subject: =?UTF-8?Q?Gr=C3=BC=C3=9Fe?=\r\n" + "Content-Type: text/plain; charset=UTF-8\r\n\r\n" + "Schöne Grüße – äöüß\r\n" pm, err := Parse([]byte(raw)) if err != nil { t.Fatalf("Parse: %v", err) } if pm.Subject != "Grüße" { t.Errorf("Subject = %q", pm.Subject) } if !strings.Contains(pm.TextBody, "Schöne Grüße – äöüß") { t.Errorf("TextBody = %q", pm.TextBody) } }