diff options
author | Marc Mutz <marc.mutz@qt.io> | 2022-07-14 18:25:18 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@qt.io> | 2022-07-26 02:06:17 +0200 |
commit | d76bf645316a13495672741e54d270bada03752c (patch) | |
tree | 0e97a5c803f036f07e611423731f2c15b62bb863 /tests/auto/corelib/text/qbytearray | |
parent | bd43c245e8c641c3a5c86762647f99658167b4db (diff) |
QByteArray: fix base64 round-trip w/more than 2GiB data
There was an explicit int cast in fromBase64Encoding() which was never
ported to qsizetype and therefore truncated the result.
Fix by removing the int cast.
Add a test, optimize it for as low memory usage as possible, given we
need to work in input and output data each in excess of 2GiB.
Fixes: QTBUG-104985
Pick-to: 6.4 6.3 6.2
Change-Id: I9c0924957e62e5cb3003132cd811b8b0315d8ac1
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'tests/auto/corelib/text/qbytearray')
-rw-r--r-- | tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp index 676c6c6cbe..823dd679e5 100644 --- a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp @@ -12,6 +12,9 @@ #include "../shared/test_number_shared.h" +#include <stdexcept> +#include <string_view> + class tst_QByteArray : public QObject { Q_OBJECT @@ -40,6 +43,7 @@ private slots: void split(); void base64_data(); void base64(); + void base64_2GiB(); void fromBase64_data(); void fromBase64(); void qvsnprintf(); @@ -575,6 +579,42 @@ void tst_QByteArray::base64() QCOMPARE(arr64, base64urlnoequals); } +void tst_QByteArray::base64_2GiB() +{ + if constexpr (sizeof(qsizetype) > sizeof(int)) { + try { + constexpr qint64 GiB = 1024 * 1024 * 1024; + static_assert((2 * GiB + 1) % 3 == 0); + const char inputChar = '\0'; // all-NULs encode as + const char outputChar = 'A'; // all-'A's + const qint64 inputSize = 2 * GiB + 1; + const qint64 outputSize = inputSize / 3 * 4; + const auto sv = [](const QByteArray &ba) { + return std::string_view{ba.data(), size_t(ba.size())}; + }; + QByteArray output; + { + const QByteArray input(inputSize, inputChar); + output = input.toBase64(); + QCOMPARE(output.size(), outputSize); + QCOMPARE(sv(output).find_first_not_of(outputChar), + std::string_view::npos); + } + { + auto r = QByteArray::fromBase64Encoding(output); + QCOMPARE_EQ(r.decodingStatus, QByteArray::Base64DecodingStatus::Ok); + QCOMPARE(r.decoded.size(), inputSize); + QCOMPARE(sv(r.decoded).find_first_not_of(inputChar), + std::string_view::npos); + } + } catch (const std::bad_alloc &) { + QSKIP("Could not allocate enough RAM."); + } + } else { + QSKIP("This is a 64-bit only test"); + } +} + //different from the previous test as the input are invalid void tst_QByteArray::fromBase64_data() { |