From 6295c40d92b95153ae5f20b552ceb3b02097ca5a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 17 Oct 2023 22:43:08 +0200 Subject: [PATCH] QStringConverter: harden encodingForName() against nullptr The nameMatch() function has an implicit precondition that neither argument is nullptr: it immediately dereferences both arguments. Prevent the crash by checking for name == nullptr early, before passing to nameMatch(). Add tests for null and empty. As a drive-by, make variables in the test const (needed for the QByteArray to avoid detaching, peer pressure for the others). Amends a639bcda1e42f48fa32885ede77f9fd320ce731c. Pick-to: 6.5 6.2 Change-Id: I4a30f6c130310eb701ba7c7251168294489c34db Reviewed-by: Ivan Solovev (cherry picked from commit b113b01a711752d3add6c9df12d84438607de5b9) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/text/qstringconverter.cpp | 2 ++ .../text/qstringconverter/tst_qstringconverter.cpp | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/corelib/text/qstringconverter.cpp b/src/corelib/text/qstringconverter.cpp index d3834d8c940..65f2b64e3f9 100644 --- a/src/corelib/text/qstringconverter.cpp +++ b/src/corelib/text/qstringconverter.cpp @@ -2082,6 +2082,8 @@ const char *QStringConverter::name() const noexcept */ std::optional QStringConverter::encodingForName(const char *name) noexcept { + if (!name) + return std::nullopt; for (qsizetype i = 0; i < LastEncoding + 1; ++i) { if (nameMatch(encodingInterfaces[i].name, name)) return QStringConverter::Encoding(i); diff --git a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp index 3202f553e8f..2886d5920f7 100644 --- a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp +++ b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp @@ -2220,14 +2220,18 @@ void tst_QStringConverter::encodingForName_data() QTest::newRow("latin1") << QByteArray("latin1") << std::optional(QStringConverter::Latin1); QTest::newRow("latin2") << QByteArray("latin2") << std::optional(); QTest::newRow("latin15") << QByteArray("latin15") << std::optional(); + QTest::newRow("") << QByteArray("") << std::optional(); + QTest::newRow("") << QByteArray(nullptr) << std::optional(); } void tst_QStringConverter::encodingForName() { - QFETCH(QByteArray, name); - QFETCH(std::optional, encoding); + QFETCH(const QByteArray, name); + QFETCH(const std::optional, encoding); - auto e = QStringConverter::encodingForName(name); + const auto *ptr = name.isNull() ? nullptr : name.data(); + + const auto e = QStringConverter::encodingForName(ptr); QCOMPARE(e, encoding); }