QSqlite: Don't crash after binding too many placeholders

When you bind more values than the query has placeholders,
indexes will be empty which causes an out-of-bounds access in indexes.first.

We can't check the parameter count because of multiple placeholders with the same name,
so we check if the name is null.

Tested with SQLite and PostgreSQL

Pick-to: 5.15
Change-Id: Id5d4bd15d7ed16603f47b87d6e0bf811a20157d8
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
This commit is contained in:
Marcel Krems 2019-09-15 01:15:16 +02:00 committed by Marcel Krems
parent fce9ec0543
commit 41a716ebbf
2 changed files with 16 additions and 1 deletions

View File

@ -478,7 +478,12 @@ bool QSQLiteResult::exec()
for (int i = 0, currentIndex = 0; i < values.size(); ++i) {
if (handledIndexes.contains(i))
continue;
const auto placeHolder = QString::fromUtf8(sqlite3_bind_parameter_name(d->stmt, currentIndex + 1));
const char *parameterName = sqlite3_bind_parameter_name(d->stmt, currentIndex + 1);
if (!parameterName) {
paramCountIsValid = false;
continue;
}
const auto placeHolder = QString::fromUtf8(parameterName);
const auto &indexes = d->indexes.value(placeHolder);
handledIndexes << indexes;
prunedValues << values.at(indexes.first());

View File

@ -2255,6 +2255,16 @@ void tst_QSqlQuery::prepare_bind_exec()
QCOMPARE(q.boundValues().at(1).toString(), utf8str);
}
// Test binding more placeholders than the query contains placeholders
q.addBindValue(8);
q.addBindValue(9);
q.addBindValue(10);
QCOMPARE(q.boundValues().size(), 3);
QCOMPARE(q.boundValues().at(0).toInt(), 8);
QCOMPARE(q.boundValues().at(1).toInt(), 9);
QCOMPARE(q.boundValues().at(2).toInt(), 10);
QFAIL_SQL(q, exec());
QVERIFY_SQL( q, exec( "SELECT * FROM " + qtest_prepare + " order by id" ) );
for ( i = 0; i < 6; ++i ) {