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 a639bcda1e.

Pick-to: 6.6 6.5 6.2
Change-Id: I4a30f6c130310eb701ba7c7251168294489c34db
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
This commit is contained in:
Marc Mutz 2023-10-17 22:43:08 +02:00
parent 8753bb3045
commit b113b01a71
2 changed files with 9 additions and 3 deletions

View File

@ -2096,6 +2096,8 @@ const char *QStringConverter::name() const noexcept
*/ */
std::optional<QStringConverter::Encoding> QStringConverter::encodingForName(const char *name) noexcept std::optional<QStringConverter::Encoding> QStringConverter::encodingForName(const char *name) noexcept
{ {
if (!name)
return std::nullopt;
for (qsizetype i = 0; i < LastEncoding + 1; ++i) { for (qsizetype i = 0; i < LastEncoding + 1; ++i) {
if (nameMatch(encodingInterfaces[i].name, name)) if (nameMatch(encodingInterfaces[i].name, name))
return QStringConverter::Encoding(i); return QStringConverter::Encoding(i);

View File

@ -2222,14 +2222,18 @@ void tst_QStringConverter::encodingForName_data()
QTest::newRow("latin1") << QByteArray("latin1") << std::optional<QStringConverter::Encoding>(QStringConverter::Latin1); QTest::newRow("latin1") << QByteArray("latin1") << std::optional<QStringConverter::Encoding>(QStringConverter::Latin1);
QTest::newRow("latin2") << QByteArray("latin2") << std::optional<QStringConverter::Encoding>(); QTest::newRow("latin2") << QByteArray("latin2") << std::optional<QStringConverter::Encoding>();
QTest::newRow("latin15") << QByteArray("latin15") << std::optional<QStringConverter::Encoding>(); QTest::newRow("latin15") << QByteArray("latin15") << std::optional<QStringConverter::Encoding>();
QTest::newRow("<empty>") << QByteArray("") << std::optional<QStringConverter::Encoding>();
QTest::newRow("<nullptr>") << QByteArray(nullptr) << std::optional<QStringConverter::Encoding>();
} }
void tst_QStringConverter::encodingForName() void tst_QStringConverter::encodingForName()
{ {
QFETCH(QByteArray, name); QFETCH(const QByteArray, name);
QFETCH(std::optional<QStringConverter::Encoding>, encoding); QFETCH(const std::optional<QStringConverter::Encoding>, encoding);
auto e = QStringConverter::encodingForName(name); const auto *ptr = name.isNull() ? nullptr : name.data();
const auto e = QStringConverter::encodingForName(ptr);
QCOMPARE(e, encoding); QCOMPARE(e, encoding);
} }