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;
|
const void *context;
|
||||||
ucnv_getToUCallBack(icu_conv, &action, &context);
|
ucnv_getToUCallBack(icu_conv, &action, &context);
|
||||||
if (context != state)
|
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);
|
ucnv_toUnicode(icu_conv, &target, targetLimit, &source, sourceLimit, nullptr, flush, &err);
|
||||||
// We did reserve enough space:
|
// We did reserve enough space:
|
||||||
@ -1999,7 +1999,7 @@ struct QStringConverterICU : QStringConverter
|
|||||||
const void *context;
|
const void *context;
|
||||||
ucnv_getFromUCallBack(icu_conv, &action, &context);
|
ucnv_getFromUCallBack(icu_conv, &action, &context);
|
||||||
if (context != state)
|
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);
|
ucnv_fromUnicode(icu_conv, &target, targetLimit, &source, sourceLimit, nullptr, flush, &err);
|
||||||
// We did reserve enough space:
|
// We did reserve enough space:
|
||||||
|
@ -540,11 +540,10 @@ void tst_QStringConverter::charByCharConsistency_data()
|
|||||||
|
|
||||||
void tst_QStringConverter::charByCharConsistency()
|
void tst_QStringConverter::charByCharConsistency()
|
||||||
{
|
{
|
||||||
QFETCH(QStringView, source);
|
QFETCH(const QStringView, source);
|
||||||
QFETCH(QByteArray, codec);
|
QFETCH(const QByteArray, codec);
|
||||||
|
|
||||||
{
|
const auto check = [&](QStringEncoder encoder){
|
||||||
QStringEncoder encoder(codec);
|
|
||||||
if (!encoder.isValid())
|
if (!encoder.isValid())
|
||||||
QSKIP("Unsupported codec");
|
QSKIP("Unsupported codec");
|
||||||
|
|
||||||
@ -555,19 +554,28 @@ void tst_QStringConverter::charByCharConsistency()
|
|||||||
stepByStepConverted += encoder.encode(codeUnit);
|
stepByStepConverted += encoder.encode(codeUnit);
|
||||||
}
|
}
|
||||||
QCOMPARE(stepByStepConverted, fullyConverted);
|
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);
|
QStringEncoder dec(codec);
|
||||||
|
check(std::move(dec));
|
||||||
QByteArray fullyConverted = encoder.encode(source);
|
|
||||||
encoder.resetState();
|
|
||||||
QByteArray stepByStepConverted;
|
|
||||||
for (const auto& codeUnit: source) {
|
|
||||||
stepByStepConverted += encoder.encode(codeUnit);
|
|
||||||
}
|
|
||||||
QCOMPARE(stepByStepConverted, fullyConverted);
|
|
||||||
}
|
}
|
||||||
|
if (QTest::currentTestResolved()) return;
|
||||||
|
|
||||||
|
{
|
||||||
|
QStringEncoder dec(codec, QStringConverter::Flag::ConvertInvalidToNull);
|
||||||
|
check(std::move(dec));
|
||||||
|
}
|
||||||
|
if (QTest::currentTestResolved()) return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QStringConverter::byteByByteConsistency_data()
|
void tst_QStringConverter::byteByByteConsistency_data()
|
||||||
@ -584,11 +592,10 @@ void tst_QStringConverter::byteByByteConsistency_data()
|
|||||||
|
|
||||||
void tst_QStringConverter::byteByByteConsistency()
|
void tst_QStringConverter::byteByByteConsistency()
|
||||||
{
|
{
|
||||||
QFETCH(QByteArray, source);
|
QFETCH(const QByteArray, source);
|
||||||
QFETCH(QByteArray, codec);
|
QFETCH(const QByteArray, codec);
|
||||||
|
|
||||||
{
|
const auto check = [&](QStringDecoder decoder) {
|
||||||
QStringDecoder decoder(codec);
|
|
||||||
if (!decoder.isValid())
|
if (!decoder.isValid())
|
||||||
QSKIP("Unsupported codec");
|
QSKIP("Unsupported codec");
|
||||||
|
|
||||||
@ -601,23 +608,28 @@ void tst_QStringConverter::byteByByteConsistency()
|
|||||||
stepByStepConverted += decoder.decode(singleChar);
|
stepByStepConverted += decoder.decode(singleChar);
|
||||||
}
|
}
|
||||||
QCOMPARE(stepByStepConverted, fullyConverted);
|
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);
|
QStringDecoder dec(codec);
|
||||||
if (!decoder.isValid())
|
check(std::move(dec));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
if (QTest::currentTestResolved()) return;
|
||||||
|
|
||||||
|
{
|
||||||
|
QStringDecoder dec(codec, QStringConverter::Flag::ConvertInvalidToNull);
|
||||||
|
check(std::move(dec));
|
||||||
|
}
|
||||||
|
if (QTest::currentTestResolved()) return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QStringConverter::statefulPieceWise()
|
void tst_QStringConverter::statefulPieceWise()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user