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 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> (cherry picked from commit d76bf645316a13495672741e54d270bada03752c) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
19f9e7c045
commit
9d036b0c67
@ -4349,7 +4349,7 @@ QByteArray::FromBase64Result QByteArray::fromBase64Encoding(QByteArray &&base64,
|
|||||||
base64.size(),
|
base64.size(),
|
||||||
base64.data(), // in-place
|
base64.data(), // in-place
|
||||||
options);
|
options);
|
||||||
base64.truncate(int(base64result.decodedLength));
|
base64.truncate(base64result.decodedLength);
|
||||||
return { std::move(base64), base64result.status };
|
return { std::move(base64), base64result.status };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4365,7 +4365,7 @@ QByteArray::FromBase64Result QByteArray::fromBase64Encoding(const QByteArray &ba
|
|||||||
base64Size,
|
base64Size,
|
||||||
const_cast<char *>(result.constData()),
|
const_cast<char *>(result.constData()),
|
||||||
options);
|
options);
|
||||||
result.truncate(int(base64result.decodedLength));
|
result.truncate(base64result.decodedLength);
|
||||||
return { std::move(result), base64result.status };
|
return { std::move(result), base64result.status };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
|
|
||||||
#include "../shared/test_number_shared.h"
|
#include "../shared/test_number_shared.h"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
class tst_QByteArray : public QObject
|
class tst_QByteArray : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -40,6 +43,7 @@ private slots:
|
|||||||
void split();
|
void split();
|
||||||
void base64_data();
|
void base64_data();
|
||||||
void base64();
|
void base64();
|
||||||
|
void base64_2GiB();
|
||||||
void fromBase64_data();
|
void fromBase64_data();
|
||||||
void fromBase64();
|
void fromBase64();
|
||||||
void qvsnprintf();
|
void qvsnprintf();
|
||||||
@ -575,6 +579,42 @@ void tst_QByteArray::base64()
|
|||||||
QCOMPARE(arr64, base64urlnoequals);
|
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
|
//different from the previous test as the input are invalid
|
||||||
void tst_QByteArray::fromBase64_data()
|
void tst_QByteArray::fromBase64_data()
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user