diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-03 09:54:26 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-03 09:54:26 +0200 |
| commit | 9d133468f43c96846220b50db56350f5df30bde4 (patch) | |
| tree | 20be0a5674d29fc5bace19a0fe45c6155d90889a | |
| parent | 5de81471ebcac21dbf8c5d781cd1b5f1df931bb8 (diff) | |
| download | qtmaildir-9d133468f43c96846220b50db56350f5df30bde4.tar.gz qtmaildir-9d133468f43c96846220b50db56350f5df30bde4.zip | |
fix: drop cached remote images when switching threads
Granting remote content on one thread, moving to another and coming back
showed the images again with the banner gone. The grant is documented as
never sticky, and it was not: verified against a local HTTP server that the
image is fetched exactly once, under the grant, and never re-requested. The
interceptor's policy was correct throughout and allowRemote was false on
return.
The images came from the engine's decoded-image cache, which is keyed on
the document and consulted before any request exists, so the interceptor is
never asked. Policy right, pane lying.
clearHttpCache() empties the profile's store but not that one. Loading
about:blank first discards the previous document along with its cached
images. This belongs in showThread() rather than render(): render() also
runs for the remote-content grant itself, where throwing the document away
would discard exactly what the user just asked to see.
Found by the task 13 checklist (item 11) and confirmed fixed by the
maintainer on screen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
| -rw-r--r-- | src/messageview.cpp | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/src/messageview.cpp b/src/messageview.cpp index f8dc4ab..b4ace55 100644 --- a/src/messageview.cpp +++ b/src/messageview.cpp @@ -148,6 +148,26 @@ void MessageView::showThread(const QList<ThreadRenderItem> &items) // Every thread starts from a clean policy: no remote grant carries over. m_interceptor->resetForNewMessage(); + // Resetting the policy is not enough on its own. Anything fetched under a + // previous grant stays in the engine's caches, and a cached resource is + // painted without the interceptor being consulted at all, so returning to + // a thread would show its remote images again with the grant switched off. + // The policy would be right and the pane would still be lying. + // + // clearHttpCache() empties the profile's store, but the render process + // keeps its own decoded-image cache keyed on the document, and that one + // outlives a setHtml() of the same URL. Loading about:blank first discards + // the previous document entirely, which is what actually drops those + // images. Verified against a local server: the image is fetched once under + // the grant and never re-fetched afterwards, so anything still visible on + // return could only have come from that cache. + // + // This belongs here rather than in render(): render() also runs for the + // remote-content grant itself, where throwing the document away would + // discard exactly what the user just asked to see. + m_profile->clearHttpCache(); + m_view->setUrl(QUrl(QStringLiteral("about:blank"))); + // Two messages in one thread commonly share a Content-ID, and the thread is // one document, so the parts are namespaced per message. const ThreadCidMap cidMap = buildThreadCidMap(m_items); |
