summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2022-05-25 09:07:37 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2022-05-25 16:38:35 +0200
commitc46ee7df57c30c94107df8506d30d8872ffa3baa (patch)
tree74e2f1c109210ec38f634699ce879bf081a2cd02
parentd83441340c210056d25777ed59ec6dab6351a55f (diff)
QStringConverter: Do not crash if invalid
Attempting to use an invalid QStringConverter would so far have resulted in a crash, as we would dereference the null iface pointer. Fix this by inserting adequate checks, and ensure that hasError returns true if we attempt to en/decode with an invalid converter. Pick-to: 6.2 6.3 Change-Id: Icf74bb88cd8c95685481cc0bd512da99b62f33e6 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r--src/corelib/text/qstringconverter.h30
-rw-r--r--tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp56
2 files changed, 82 insertions, 4 deletions
diff --git a/src/corelib/text/qstringconverter.h b/src/corelib/text/qstringconverter.h
index 213de9fe55..c1645f0938 100644
--- a/src/corelib/text/qstringconverter.h
+++ b/src/corelib/text/qstringconverter.h
@@ -62,12 +62,23 @@ public:
#endif
qsizetype requiredSpace(qsizetype inputLength) const
- { return iface->fromUtf16Len(inputLength); }
+ { return iface ? iface->fromUtf16Len(inputLength) : 0; }
char *appendToBuffer(char *out, QStringView in)
- { return iface->fromUtf16(out, in, &state); }
+ {
+ if (!iface) {
+ state.invalidChars = 1;
+ return out;
+ }
+ return iface->fromUtf16(out, in, &state);
+ }
private:
QByteArray encodeAsByteArray(QStringView in)
{
+ if (!iface) {
+ // ensure that hasError returns true
+ state.invalidChars = 1;
+ return {};
+ }
QByteArray result(iface->fromUtf16Len(in.size()), Qt::Uninitialized);
char *out = result.data();
out = iface->fromUtf16(out, in, &state);
@@ -120,12 +131,23 @@ public:
#endif
qsizetype requiredSpace(qsizetype inputLength) const
- { return iface->toUtf16Len(inputLength); }
+ { return iface ? iface->toUtf16Len(inputLength) : 0; }
QChar *appendToBuffer(QChar *out, QByteArrayView ba)
- { return iface->toUtf16(out, ba, &state); }
+ {
+ if (!iface) {
+ state.invalidChars = 1;
+ return out;
+ }
+ return iface->toUtf16(out, ba, &state);
+ }
private:
QString decodeAsString(QByteArrayView in)
{
+ if (!iface) {
+ // ensure that hasError returns true
+ state.invalidChars = 1;
+ return {};
+ }
QString result(iface->toUtf16Len(in.size()), Qt::Uninitialized);
const QChar *out = iface->toUtf16(result.data(), in, &state);
result.truncate(out - result.constData());
diff --git a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp
index 6fe20b1453..231df0390e 100644
--- a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp
+++ b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp
@@ -120,6 +120,8 @@ private slots:
void constructByName();
+ void invalidConverter();
+
void convertUtf8_data();
void convertUtf8();
void convertUtf8CharByChar_data() { convertUtf8_data(); }
@@ -181,6 +183,60 @@ void tst_QStringConverter::constructByName()
QVERIFY(!strcmp(decoder.name(), "UTF-16"));
}
+void tst_QStringConverter::invalidConverter()
+{
+ // QStringEncoder tests
+ {
+ QStringEncoder encoder;
+ QVERIFY(!encoder.isValid());
+ QVERIFY(!encoder.name());
+ QByteArray encoded = encoder(u"Some text");
+ QVERIFY(encoded.isEmpty());
+ QVERIFY(encoder.hasError());
+
+ encoder.resetState();
+ QVERIFY(!encoder.hasError());
+
+ encoded = encoder.encode(u"More text");
+ QVERIFY(encoded.isEmpty());
+ QVERIFY(encoder.hasError());
+ QCOMPARE(encoder.requiredSpace(42), 0);
+
+ encoder.resetState();
+ QVERIFY(!encoder.hasError());
+ char buffer[100];
+ char *position = encoder.appendToBuffer(buffer, u"Even more");
+ QCOMPARE(position, buffer);
+ QVERIFY(encoder.hasError());
+ }
+
+ // QStringDecoder tests
+ {
+ QStringDecoder decoder;
+ QVERIFY(!decoder.name());
+ QVERIFY(!decoder.isValid());
+ QString decoded = decoder("Some text");
+ QVERIFY(decoded.isEmpty());
+ QVERIFY(decoder.hasError());
+
+ decoder.resetState();
+ QVERIFY(!decoder.hasError());
+
+ decoded = decoder.decode("More text");
+ QVERIFY(decoded.isEmpty());
+ QVERIFY(decoder.hasError());
+
+ QCOMPARE(decoder.requiredSpace(42), 0);
+
+ decoder.resetState();
+ QVERIFY(!decoder.hasError());
+ QChar buffer[100];
+ QChar *position = decoder.appendToBuffer(buffer, "Even more");
+ QCOMPARE(position, buffer);
+ QVERIFY(decoder.hasError());
+ }
+}
+
void tst_QStringConverter::convertUtf8_data()
{
QTest::addColumn<QStringConverter::Encoding>("encoding");