fix(mailparser): kaputte/truncated Multipart-Mails partiell indexieren statt scheitern
Bei NextPart()-Fehler (EOF, malformed header) wird der bereits geparste Inhalt zurückgegeben statt der gesamte Parse abgebrochen. parseMultipart() gibt keinen Fehler mehr zurück — partieller Text/HTML ist besser als gar kein Index-Eintrag. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
5e7ae6e056
commit
0ccbd5bafb
@@ -180,9 +180,9 @@ func Parse(raw []byte) (*ParsedMail, error) {
|
||||
|
||||
if strings.HasPrefix(mediaType, "multipart/") {
|
||||
boundary := params["boundary"]
|
||||
if err := parseMultipart(pm, msg.Body, boundary); err != nil {
|
||||
return nil, fmt.Errorf("mailparser: multipart: %w", err)
|
||||
}
|
||||
// Ignore parse errors — return partial content instead of failing completely.
|
||||
// Malformed/truncated multipart emails still get metadata + whatever parts parsed.
|
||||
parseMultipart(pm, msg.Body, boundary) //nolint:errcheck
|
||||
} else {
|
||||
body, _ := io.ReadAll(msg.Body)
|
||||
decoded := decodeBody(body, msg.Header.Get("Content-Transfer-Encoding"))
|
||||
@@ -198,15 +198,14 @@ func Parse(raw []byte) (*ParsedMail, error) {
|
||||
}
|
||||
|
||||
// parseMultipart walks MIME parts and fills text, html, and attachments.
|
||||
func parseMultipart(pm *ParsedMail, body io.Reader, boundary string) error {
|
||||
// Truncated or malformed parts are skipped — partial content is better than nothing.
|
||||
func parseMultipart(pm *ParsedMail, body io.Reader, boundary string) {
|
||||
mr := multipart.NewReader(body, boundary)
|
||||
for {
|
||||
part, err := mr.NextPart()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
// io.EOF = normal end; any other error = truncated/malformed — stop here.
|
||||
break
|
||||
}
|
||||
|
||||
ct := part.Header.Get("Content-Type")
|
||||
@@ -244,9 +243,7 @@ func parseMultipart(pm *ParsedMail, body io.Reader, boundary string) error {
|
||||
|
||||
// Nested multipart
|
||||
if strings.HasPrefix(mediaType, "multipart/") {
|
||||
if err := parseMultipart(pm, bytes.NewReader(decoded), params["boundary"]); err != nil {
|
||||
return err
|
||||
}
|
||||
parseMultipart(pm, bytes.NewReader(decoded), params["boundary"])
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -257,7 +254,6 @@ func parseMultipart(pm *ParsedMail, body io.Reader, boundary string) error {
|
||||
pm.HTMLBody += string(decoded)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// decodeCharset converts data from the declared MIME charset to UTF-8.
|
||||
|
||||
Reference in New Issue
Block a user