MailJDTourDownloadDocsQualityTestsCoverage

Which source lines and branches the tests execute. Lines 91.5 %, branches 75.0 % (minimum 85 % and 72 %). main @ 399ffe3d · 21 October 2026 · pipeline 7238.

GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 28.2% 11 / 0 / 39
Functions: 40.0% 2 / 0 / 5
Branches: 7.4% 6 / 0 / 81

ui/HtmlDocumentDelivery.cpp
Line Branch Exec Source
1 #include "HtmlDocumentDelivery.h"
2
3 #include <QBuffer>
4 #include <utility>
5 #include <QUuid>
6 #include <QWebEngineUrlRequestJob>
7 #include <QWebEngineUrlScheme>
8
9 namespace {
10 // Qt requires scheme registration before QApplication, including in test and
11 // runtime-probe entry points. The linked reader translation unit registers
12 // only the syntax; no page, profile, handler or renderer is constructed here.
13 53 [[maybe_unused]] const bool registered = [] {
14
2/2
✓ Branch 2 → 3 taken 53 times.
✓ Branch 3 → 4 taken 53 times.
53 QWebEngineUrlScheme scheme(HtmlDocumentDelivery::Scheme);
15
1/1
✓ Branch 5 → 6 taken 53 times.
53 scheme.setSyntax(QWebEngineUrlScheme::Syntax::Host);
16
1/1
✓ Branch 7 → 8 taken 53 times.
53 scheme.setFlags(QWebEngineUrlScheme::NoAccessAllowed);
17 // Opaque origins prevent decoded images from an earlier opt-in bypassing
18 // the next document's request policy. Keep CSP; grant no local-file access, CORS,
19 // JavaScript fetch, service-worker or source-view privileges. The private
20 // profile and current token constrain access to this one display lease.
21
1/1
✓ Branch 8 → 9 taken 53 times.
53 QWebEngineUrlScheme::registerScheme(scheme);
22 53 return true;
23 53 }();
24 }
25
26 ✗ bool HtmlDocumentDelivery::fitsDataUrl(const QByteArray &html) {
27 // Chromium caps URL length at 2 MiB. Reserve room for the MIME prefix and
28 // count escaping without allocating another percent-encoded payload.
29 ✗ constexpr qsizetype limit = 2 * 1024 * 1024 - 1024;
30 ✗ if (html.size() > limit) return false;
31 ✗ if (html.size() <= limit / 3) return true;
32 ✗ qsizetype encoded = 0;
33 ✗ for (unsigned char byte : html) {
34 ✗ const bool unreserved = (byte >= 'a' && byte <= 'z') ||
35 ✗ (byte >= 'A' && byte <= 'Z') || (byte >= '0' && byte <= '9') ||
36 ✗ byte == '-' || byte == '_' || byte == '.' || byte == '~';
37 ✗ encoded += unreserved ? 1 : 3;
38 ✗ if (encoded > limit) return false;
39 }
40 ✗ return true;
41 }
42
43 ✗ QUrl HtmlDocumentDelivery::publish(QByteArray html) {
44 ✗ clear();
45 ✗ if (html.isEmpty() || html.size() > MaxDocumentBytes) return {};
46 ✗ m_html = std::move(html);
47 ✗ m_url = QUrl(QStringLiteral("mailjd-html://document/") +
48 ✗ QUuid::createUuid().toString(QUuid::WithoutBraces));
49 ✗ return m_url;
50 }
51
52 8691 void HtmlDocumentDelivery::clear() {
53
1/1
✓ Branch 2 → 3 taken 8691 times.
8691 m_url = QUrl();
54 8691 m_html.clear();
55 8691 }
56
57 ✗ void HtmlDocumentDelivery::requestStarted(QWebEngineUrlRequestJob *request) {
58 ✗ if (request->requestMethod() != QByteArrayLiteral("GET") ||
59 ✗ m_url.isEmpty() || request->requestUrl() != m_url) {
60 ✗ request->fail(QWebEngineUrlRequestJob::RequestDenied);
61 ✗ return;
62 }
63 // QByteArray shares the immutable payload. The request owns its read cursor
64 // and keeps the bytes alive only until Chromium finishes/cancels the job.
65 ✗ auto *buffer = new QBuffer(request);
66 ✗ buffer->setData(m_html);
67 ✗ buffer->open(QIODevice::ReadOnly);
68 ✗ request->reply(QByteArrayLiteral("text/html"), buffer);
69 }
70