diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/fixtures/body_with_content_id.eml | 20 | ||||
| -rw-r--r-- | tests/test_mimeparser.cpp | 31 |
2 files changed, 51 insertions, 0 deletions
diff --git a/tests/fixtures/body_with_content_id.eml b/tests/fixtures/body_with_content_id.eml new file mode 100644 index 0000000..dd0f6be --- /dev/null +++ b/tests/fixtures/body_with_content_id.eml @@ -0,0 +1,20 @@ +From: Bulk Sender <news@example.org> +Subject: Body part carrying a content id +Date: Sat, 01 Aug 2026 10:00:00 +0000 +Message-ID: <body-cid-1@example.org> +MIME-Version: 1.0 +Content-Type: multipart/related; boundary="REL" + +--REL +Content-Type: text/html; charset=utf-8 +Content-ID: <body@example.org> + +<html><body><p>Body text.</p><img src="cid:logo@example.org"></body></html> +--REL +Content-Type: image/png +Content-Transfer-Encoding: base64 +Content-ID: <logo@example.org> + +iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9 +awAAAABJRU5ErkJggg== +--REL-- diff --git a/tests/test_mimeparser.cpp b/tests/test_mimeparser.cpp index f1bbc8a..d16735f 100644 --- a/tests/test_mimeparser.cpp +++ b/tests/test_mimeparser.cpp @@ -31,6 +31,7 @@ private slots: void prefersHtmlWhenAvailable(); void fallsBackToPlainWhenHtmlDisabled(); void collectsInlineCidParts(); + void aBodyCarryingAContentIdStillRenders(); void decodesQuotedPrintableAttachment(); void decodesEncodedHeaders(); void malformedMessageDoesNotCrash(); @@ -109,6 +110,36 @@ void TestMimeParser::collectsInlineCidParts() QVERIFY(part.data.startsWith(QByteArray("\x89PNG", 4))); } +void TestMimeParser::aBodyCarryingAContentIdStillRenders() +{ + // Reported by the user: a bulk sender's message opened blank, with the app + // saying it had no HTML part. + // + // A Content-Id makes a part referenceable, not non-displayable, and setting + // one on the text/html body is legal and common. collectParts filed any + // part with an id into inlineParts and returned before the body branches, + // so such a message parsed with both body slots empty. + MimeParser parser; + const ParsedMessage msg = + parser.parse(fixture(QStringLiteral("body_with_content_id.eml"))); + + QVERIFY(msg.ok); + + // The body fills its slot despite the id. + QVERIFY2(msg.hasHtml(), "the html body was swallowed by its own content id"); + QVERIFY(msg.htmlBody.contains(QStringLiteral("Body text."))); + + // And it stays reachable under that id, so a sibling referencing it still + // resolves. Register first, then assign: the two are independent. + QVERIFY(msg.inlineParts.contains(QStringLiteral("body@example.org"))); + QCOMPARE(msg.inlineParts.value(QStringLiteral("body@example.org")).mimeType, + QStringLiteral("text/html")); + + // The genuinely inline image is untouched by the change. + QVERIFY(msg.inlineParts.contains(QStringLiteral("logo@example.org"))); + QCOMPARE(msg.inlineParts.size(), 2); +} + void TestMimeParser::decodesQuotedPrintableAttachment() { MimeParser parser; |
