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> Pick-to: 6.7 6.5 Change-Id: I70d4dc00e3e0db6cad964579662bcf6d185a4c34 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
488545ca72
commit
39bbfce9b6
@ -1976,7 +1976,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:
|
||||||
@ -2009,7 +2009,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:
|
||||||
|
@ -571,11 +571,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");
|
||||||
|
|
||||||
@ -586,19 +585,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()
|
||||||
@ -615,11 +623,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");
|
||||||
|
|
||||||
@ -632,23 +639,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