QStringConverterICU: Pass correct pointer to callback

Pass the pointer to the current state, not a pointer to a pointer to it.

[ChangeLog][QtCore][QStringConverter] Fixed a bug involving moved
QStringEncoder/QStringDecoder objects accessing invalid state.

Amends 122270d6bea164e6df4357f4d4d77aacfa430470.

Done-with: Marc Mutz <marc.mutz@qt.io>
Change-Id: I70d4dc00e3e0db6cad964579662bcf6d185a4c34
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
(cherry picked from commit 39bbfce9b675c9085ef49c9b9c52c146eca55e4a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 7c4e1357e49baebdd2d20710fccb5604cbb36c0d)
This commit is contained in:
Fabian Kosmale 2024-04-18 10:25:21 +02:00 committed by Tarja Sundqvist
parent ac21796c2f
commit 72e405b907
2 changed files with 46 additions and 34 deletions

View File

@ -1966,7 +1966,7 @@ struct QStringConverterICU : QStringConverter
const void *context;
ucnv_getToUCallBack(icu_conv, &action, &context);
if (context != state)
ucnv_setToUCallBack(icu_conv, action, &state, nullptr, nullptr, &err);
ucnv_setToUCallBack(icu_conv, action, state, nullptr, nullptr, &err);
ucnv_toUnicode(icu_conv, &target, targetLimit, &source, sourceLimit, nullptr, flush, &err);
// We did reserve enough space:
@ -1999,7 +1999,7 @@ struct QStringConverterICU : QStringConverter
const void *context;
ucnv_getFromUCallBack(icu_conv, &action, &context);
if (context != state)
ucnv_setFromUCallBack(icu_conv, action, &state, nullptr, nullptr, &err);
ucnv_setFromUCallBack(icu_conv, action, state, nullptr, nullptr, &err);
ucnv_fromUnicode(icu_conv, &target, targetLimit, &source, sourceLimit, nullptr, flush, &err);
// We did reserve enough space:

View File

@ -540,11 +540,10 @@ void tst_QStringConverter::charByCharConsistency_data()
void tst_QStringConverter::charByCharConsistency()
{
QFETCH(QStringView, source);
QFETCH(QByteArray, codec);
QFETCH(const QStringView, source);
QFETCH(const QByteArray, codec);
{
QStringEncoder encoder(codec);
const auto check = [&](QStringEncoder encoder){
if (!encoder.isValid())
QSKIP("Unsupported codec");
@ -555,19 +554,28 @@ void tst_QStringConverter::charByCharConsistency()
stepByStepConverted += encoder.encode(codeUnit);
}
QCOMPARE(stepByStepConverted, fullyConverted);
}
};
check(QStringEncoder(codec));
if (QTest::currentTestResolved()) return;
check(QStringEncoder(codec, QStringConverter::Flag::ConvertInvalidToNull));
if (QTest::currentTestResolved()) return;
// moved codecs also work:
{
QStringEncoder encoder(codec, QStringConverter::Flag::ConvertInvalidToNull);
QByteArray fullyConverted = encoder.encode(source);
encoder.resetState();
QByteArray stepByStepConverted;
for (const auto& codeUnit: source) {
stepByStepConverted += encoder.encode(codeUnit);
}
QCOMPARE(stepByStepConverted, fullyConverted);
QStringEncoder dec(codec);
check(std::move(dec));
}
if (QTest::currentTestResolved()) return;
{
QStringEncoder dec(codec, QStringConverter::Flag::ConvertInvalidToNull);
check(std::move(dec));
}
if (QTest::currentTestResolved()) return;
}
void tst_QStringConverter::byteByByteConsistency_data()
@ -584,11 +592,10 @@ void tst_QStringConverter::byteByByteConsistency_data()
void tst_QStringConverter::byteByByteConsistency()
{
QFETCH(QByteArray, source);
QFETCH(QByteArray, codec);
QFETCH(const QByteArray, source);
QFETCH(const QByteArray, codec);
{
QStringDecoder decoder(codec);
const auto check = [&](QStringDecoder decoder) {
if (!decoder.isValid())
QSKIP("Unsupported codec");
@ -601,23 +608,28 @@ void tst_QStringConverter::byteByByteConsistency()
stepByStepConverted += decoder.decode(singleChar);
}
QCOMPARE(stepByStepConverted, fullyConverted);
}
};
check(QStringDecoder(codec));
if (QTest::currentTestResolved()) return;
check(QStringDecoder(codec, QStringConverter::Flag::ConvertInvalidToNull));
if (QTest::currentTestResolved()) return;
// moved codecs also work:
{
QStringDecoder decoder(codec, QStringConverter::Flag::ConvertInvalidToNull);
if (!decoder.isValid())
QSKIP("Unsupported codec");
QString fullyConverted = decoder.decode(source);
decoder.resetState();
QString stepByStepConverted;
for (const auto& byte: source) {
QByteArray singleChar;
singleChar.append(byte);
stepByStepConverted += decoder.decode(singleChar);
}
QCOMPARE(stepByStepConverted, fullyConverted);
QStringDecoder dec(codec);
check(std::move(dec));
}
if (QTest::currentTestResolved()) return;
{
QStringDecoder dec(codec, QStringConverter::Flag::ConvertInvalidToNull);
check(std::move(dec));
}
if (QTest::currentTestResolved()) return;
}
void tst_QStringConverter::statefulPieceWise()