diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-02 17:46:21 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-02 17:46:21 +0200 |
| commit | 2a10cebcfb978ce7c5f03a97473eafe9bb3d15dd (patch) | |
| tree | faec2dc7b5d9be72fac5e091b81eed3491d3c2d6 /src/cidschemehandler.h | |
| parent | 8ecd5a8e83380f543b856ff28226a8e15fd7dc96 (diff) | |
| download | qtmaildir-2a10cebcfb978ce7c5f03a97473eafe9bb3d15dd.tar.gz qtmaildir-2a10cebcfb978ce7c5f03a97473eafe9bb3d15dd.zip | |
feat: add HTML builder and cid: scheme handler
HtmlBuilder renders parsed messages (and whole threads, as one document,
so newsletter threads don't spawn one Chromium process per message) into
the HTML string the web view loads. Plain text is escaped and quote lines
marked; the cid: rewrite is namespaced per message ("<prefix>!<id>") so
two thread messages sharing a Content-ID don't collide.
Hardened namespaceCids beyond the initial sketch after attacking it:
handles unquoted cid: attribute values, background=/poster= (not just
src/href), and CSS url(cid:...) in both style="" attributes and <style>
blocks, all case-insensitively. Replaced the greedy [^"']+ capture with
per-quote-style alternation so two cid: refs on one line can't bleed into
each other.
CidSchemeHandler serves cid: requests from the thread's inline-parts map,
keyed by the same namespaced string, replaced wholesale per thread.
Diffstat (limited to 'src/cidschemehandler.h')
| -rw-r--r-- | src/cidschemehandler.h | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/cidschemehandler.h b/src/cidschemehandler.h new file mode 100644 index 0000000..56e6ea1 --- /dev/null +++ b/src/cidschemehandler.h @@ -0,0 +1,30 @@ +#pragma once + +#include <QHash> +#include <QWebEngineUrlSchemeHandler> + +#include "mimeparser.h" + +/// Serves cid: URLs from the currently displayed thread only. +/// +/// Keys are the namespaced form "<prefix>!<content-id>" produced by +/// HtmlBuilder, so two messages in one thread that share a Content-ID do not +/// collide. The map is replaced wholesale on every thread change, so a thread +/// can never reference another thread's parts. +class CidSchemeHandler : public QWebEngineUrlSchemeHandler +{ + Q_OBJECT +public: + explicit CidSchemeHandler(QObject *parent = nullptr); + + void setParts(const QHash<QString, InlinePart> &parts) { m_parts = parts; } + + /// Builds the namespaced key HtmlBuilder's rewritten URLs will request. + static QString namespacedKey(const QString &prefix, const QString &contentId) + { return prefix + QLatin1Char('!') + contentId; } + + void requestStarted(QWebEngineUrlRequestJob *job) override; + +private: + QHash<QString, InlinePart> m_parts; +}; |
