From c140d9ab8ee5d56f6a024d156e6fe45cda13a026 Mon Sep 17 00:00:00 2001 From: Ahmad Samir Date: Sun, 4 May 2025 20:13:50 +0300 Subject: [PATCH] qdataurl: modify the percent-decoded byte array directly Parse the content-type first, then slice the byte array. This is useful especially for large base64 payloads. Drive-by, use QUrl::toEncoded(), it's the same result but more succinct syntax; pointed out in code review. Also remove an old comment, it's not relevant anymore since QUrl::encodedPath() isn't available any more in Qt 6.0: https://code.qt.io/cgit/qt/qt.git/commit/?id=c0d237b7aa6e0257e3c3eee7336deaed1cf68252 Change-Id: Id69345f315dab934d0f2867008bf4fe29d63cac9 Reviewed-by: Thiago Macieira --- src/corelib/io/qdataurl.cpp | 45 ++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/corelib/io/qdataurl.cpp b/src/corelib/io/qdataurl.cpp index 86a5175b708..23bc114d9d4 100644 --- a/src/corelib/io/qdataurl.cpp +++ b/src/corelib/io/qdataurl.cpp @@ -30,34 +30,14 @@ Q_CORE_EXPORT bool qDecodeDataUrl(const QUrl &uri, QString &mimeType, QByteArray if (uri.scheme() != "data"_L1 || !uri.host().isEmpty()) return false; - // the following would have been the correct thing, but - // reality often differs from the specification. People have - // data: URIs with ? and # - //QByteArray data = QByteArray::fromPercentEncoding(uri.path(QUrl::FullyEncoded).toLatin1()); - const QByteArray dataArray = - QByteArray::fromPercentEncoding(uri.url(QUrl::FullyEncoded | QUrl::RemoveScheme).toLatin1()); - auto data = QLatin1StringView{dataArray}; - + payload = QByteArray::fromPercentEncoding(uri.toEncoded(QUrl::RemoveScheme)); // parse it: - const qsizetype pos = data.indexOf(u','); + const qsizetype pos = payload.indexOf(','); if (pos != -1) { - payload = QByteArray{data.sliced(pos + 1)}; + auto data = QLatin1StringView{payload}; data.truncate(pos); data = data.trimmed(); - // find out if the payload is encoded in Base64 - constexpr auto base64 = ";base64"_L1; // per the RFC, at the end of `data` - if (data.endsWith(base64, Qt::CaseInsensitive)) { - auto r = QByteArray::fromBase64Encoding(std::move(payload)); - if (!r) { - // just in case someone uses `payload` without checking the returned bool - payload = {}; - return false; // decoding failed - } - payload = std::move(r.decoded); - data.chop(base64.size()); - } - QLatin1StringView mime; QLatin1StringView charsetParam; constexpr auto charset = "charset"_L1; @@ -88,7 +68,26 @@ Q_CORE_EXPORT bool qDecodeDataUrl(const QUrl &uri, QString &mimeType, QByteArray else mimeType = mime; + // find out if the payload is encoded in Base64 + constexpr auto base64 = ";base64"_L1; // per the RFC, at the end of `data` + const bool isBas64 = data.endsWith(base64, Qt::CaseInsensitive); + + payload.slice(pos + 1); + data = {}; + + if (isBas64) { + auto r = QByteArray::fromBase64Encoding(std::move(payload)); + if (!r) { + // just in case someone uses `payload` without checking the returned bool + payload = {}; + return false; // decoding failed + } + payload = std::move(r.decoded); + } + return true; + } else { + payload = {}; } return false;