summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMårten Nordheim <marten.nordheim@qt.io>2023-10-30 16:51:58 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-11-09 13:35:14 +0000
commit8296051ae73cbc35823dced6d628b2ae36ba8825 (patch)
tree2cb3725353bf52b43e4ee1ad5557bae1df3bd7ce
parent6e367fbb307d0b9f26af64611b8e477e7cce1ea1 (diff)
QLocal8Bit::convertToUnicode[win]: Support stateless flag
By just setting state to nullptr. Pick-to: 6.5 Task-number: QTBUG-105105 Change-Id: I6b4f8fe39f1ba51dcfaf98ce7e42c2acd4c4cf98 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> (cherry picked from commit 10f5e4f8099136bce59f5f859df89c5b2e695fc9) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/corelib/text/qstringconverter.cpp5
-rw-r--r--tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp37
2 files changed, 41 insertions, 1 deletions
diff --git a/src/corelib/text/qstringconverter.cpp b/src/corelib/text/qstringconverter.cpp
index 7d7dd35dce..0d0a885d70 100644
--- a/src/corelib/text/qstringconverter.cpp
+++ b/src/corelib/text/qstringconverter.cpp
@@ -1270,6 +1270,9 @@ QString QLocal8Bit::convertToUnicode_sys(QByteArrayView in, quint32 codePage,
const char *mb = in.data();
int mblen = length;
+ if (state && state->flags & QStringConverter::Flag::Stateless)
+ state = nullptr;
+
if (!mb || !mblen)
return QString();
@@ -1327,7 +1330,7 @@ QString QLocal8Bit::convertToUnicode_sys(QByteArrayView in, quint32 codePage,
}
Q_ASSERT(mblen > 0);
- Q_ASSERT(state->remainingChars == 0);
+ Q_ASSERT(!state || state->remainingChars == 0);
while (!(len = MultiByteToWideChar(codePage, MB_ERR_INVALID_CHARS, mb, mblen, out,
int(outlen)))) {
diff --git a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp
index 9b33b46421..3202f553e8 100644
--- a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp
+++ b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp
@@ -2523,6 +2523,14 @@ void tst_QStringConverter::fromLocal8Bit()
result += QLocal8Bit::convertToUnicode_sys({&c, 1}, codePage, &state);
QCOMPARE(result, utf16);
QCOMPARE(state.remainingChars, 0);
+
+ result.clear();
+ state.clear();
+ // Decode the full string again, this time without state
+ state.flags |= QStringConverter::Flag::Stateless;
+ result = QLocal8Bit::convertToUnicode_sys(eightBit, codePage, &state);
+ QCOMPARE(result, utf16);
+ QCOMPARE(state.remainingChars, 0);
}
void tst_QStringConverter::fromLocal8Bit_special_cases()
@@ -2539,6 +2547,17 @@ void tst_QStringConverter::fromLocal8Bit_special_cases()
QCOMPARE(result, u"こ");
QCOMPARE(state.remainingChars, 0);
+ // And without state:
+ result.clear();
+ QStringConverter::State statelessState;
+ statelessState.flags |= QStringConverter::Flag::Stateless;
+ result = QLocal8Bit::convertToUnicode_sys("\x82", SHIFT_JIS, &statelessState);
+ result += QLocal8Bit::convertToUnicode_sys("\xb1", SHIFT_JIS, &statelessState);
+ // 0xb1 is a valid single-octet character in Shift-JIS, so the output
+ // isn't really what you would expect:
+ QCOMPARE(result, QString(QChar::ReplacementCharacter) + u'ア');
+ QCOMPARE(statelessState.remainingChars, 0);
+
// Now try a 3-octet UTF-8 sequence:
result.clear();
state.clear();
@@ -2600,6 +2619,14 @@ void tst_QStringConverter::toLocal8Bit()
result += QLocal8Bit::convertFromUnicode_sys(QStringView(&c, 1), codePage, &state);
QCOMPARE(result, eightBit);
QCOMPARE(state.remainingChars, 0);
+
+ result.clear();
+ state.clear();
+ // Decode the full string again, this time without state
+ state.flags |= QStringConverter::Flag::Stateless;
+ result = QLocal8Bit::convertFromUnicode_sys(utf16, codePage, &state);
+ QCOMPARE(result, eightBit);
+ QCOMPARE(state.remainingChars, 0);
}
void tst_QStringConverter::toLocal8Bit_special_cases()
@@ -2622,6 +2649,16 @@ void tst_QStringConverter::toLocal8Bit_special_cases()
// Retain compat with the behavior for toLocal8Bit:
QCOMPARE(codeUnits.first(1).toLocal8Bit(), "?");
+ // QString::toLocal8Bit is already stateless, but test stateless handling
+ // explicitly anyway:
+ result.clear();
+ QStringConverter::State statelessState;
+ statelessState.flags |= QStringConverter::Flag::Stateless;
+ result = QLocal8Bit::convertFromUnicode_sys(codeUnits.first(1), UTF8, &statelessState);
+ result += QLocal8Bit::convertFromUnicode_sys(codeUnits.sliced(1), UTF8, &statelessState);
+ // Windows uses the replacement character for invalid characters:
+ QCOMPARE(result, "\ufffd\ufffd");
+
// Now do the same, but the second time we feed in a character, we also
// provide many more so the internal stack buffer is not large enough.
result.clear();