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:
parent
ac21796c2f
commit
72e405b907
@ -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:
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user