/* * qtmaildir - a Qt6 mail client for notmuch-indexed Maildirs * Copyright (C) 2026 Danilo M. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "cidschemehandler.h" #include "htmlbuilder.h" class TestHtmlBuilder : public QObject { Q_OBJECT private slots: void escapesPlainText(); void preservesHtmlBodyWhenHtmlRequested(); void marksQuotedLines(); void plainTextScriptTagIsNeutralised(); void buildsThreadWithAllMessages(); void collapsedMessageShowsStubOnly(); void threadNamespacesCidUrls(); // Adversarial additions. void namespacesUnquotedCidAttribute(); void namespacesCaseInsensitiveAttributeName(); void namespacesCidInBackgroundAttribute(); void namespacesCidInInlineStyleUrl(); void namespacesCidInStyleBlock(); void namespacesMultipleCidRefsOnOneLine(); void namespacesWhitespaceAroundEquals(); void namespacedKeyRejectsPrefixContainingSeparator(); }; void TestHtmlBuilder::escapesPlainText() { ParsedMessage msg; msg.ok = true; msg.plainBody = QStringLiteral("a < b & c > d"); const QString html = HtmlBuilder::build(msg, HtmlBuilder::ForcePlain); QVERIFY(html.contains(QStringLiteral("a < b & c > d"))); } void TestHtmlBuilder::preservesHtmlBodyWhenHtmlRequested() { ParsedMessage msg; msg.ok = true; msg.htmlBody = QStringLiteral("

hello

"); const QString html = HtmlBuilder::build(msg, HtmlBuilder::PreferHtml); QVERIFY(html.contains(QStringLiteral("

hello

"))); } void TestHtmlBuilder::marksQuotedLines() { ParsedMessage msg; msg.ok = true; msg.plainBody = QStringLiteral("reply\n> quoted\nend"); const QString html = HtmlBuilder::build(msg, HtmlBuilder::ForcePlain); QVERIFY(html.contains(QStringLiteral("class=\"quote\""))); } void TestHtmlBuilder::plainTextScriptTagIsNeutralised() { ParsedMessage msg; msg.ok = true; msg.plainBody = QStringLiteral(""); const QString html = HtmlBuilder::build(msg, HtmlBuilder::ForcePlain); // Escaped, not embedded. (JavaScript is also disabled at the profile level, // so this is the second of two independent defences.) QVERIFY(!html.contains(QStringLiteral("