tst_QSqlQuery: fix UBs (invalid downcasts, member calls)

The existing code derived a helper class from QSqlResult and
overloaded two protected functions as public ones so the test
could call them after casting QSqlResults to that helper class.

Both the cast (which is a C-style cast, but with combined
static_cast and const_cast semanics) and the following member
function call are undefined behavior.

Fix by making the test class a friend of QSqlResult, and
dropping the casts.

Change-Id: I09de2e2b46976d01cfce25892aec6ad36881d3eb
Reviewed-by: Mark Brand <mabrand@mabrand.nl>
This commit is contained in:
Marc Mutz 2016-03-12 15:03:16 +01:00
parent 52a599bb56
commit add95c5510
2 changed files with 37 additions and 50 deletions

View File

@ -38,6 +38,9 @@
#include <QtCore/qvector.h>
#include <QtSql/qsql.h>
// for testing:
class tst_QSqlQuery;
QT_BEGIN_NAMESPACE
@ -54,6 +57,8 @@ class Q_SQL_EXPORT QSqlResult
Q_DECLARE_PRIVATE(QSqlResult)
friend class QSqlQuery;
friend class QSqlTableModelPrivate;
// for testing:
friend class ::tst_QSqlQuery;
public:
virtual ~QSqlResult();

View File

@ -1753,24 +1753,6 @@ void tst_QSqlQuery::synonyms()
QCOMPARE( rec.field( 2 ).name().toLower(), QString( "t_varchar" ) );
}
// This class is used to test protected QSqlResult methods
class ResultHelper: public QSqlResult
{
public:
ResultHelper(): QSqlResult( 0 ) {} // don't call, it's only for stupid compilers
bool execBatch( bool bindArray = false )
{
return QSqlResult::execBatch( bindArray );
}
QString boundValueName( int pos ) const
{
return QSqlResult::boundValueName( pos );
}
};
// It doesn't make sense to split this into several tests
void tst_QSqlQuery::prepare_bind_exec()
{
@ -1895,81 +1877,81 @@ void tst_QSqlQuery::prepare_bind_exec()
q.bindValue( 0, 0 );
q.bindValue( 1, values[ 0 ] );
QCOMPARE( q.boundValues().size(), 2 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 0 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[0] );
QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 0);
QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[0]);
QVERIFY_SQL( q, exec() );
QCOMPARE( q.boundValues().size(), 2 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 0 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[0] );
QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 0);
QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[0]);
q.addBindValue( 1 );
q.addBindValue( values[ 1 ] );
QCOMPARE( q.boundValues().size(), 2 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 1 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[1] );
QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 1);
QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[1]);
QVERIFY_SQL( q, exec() );
QCOMPARE( q.boundValues().size(), 2 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 1 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[1] );
QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 1);
QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[1]);
q.addBindValue( 2 );
q.addBindValue( values[ 2 ] );
QCOMPARE( q.boundValues().size(), 2 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 2 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[2] );
QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 2);
QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[2]);
QVERIFY_SQL( q, exec() );
QCOMPARE( q.boundValues().size(), 2 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 2 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[2] );
QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 2);
QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[2]);
q.addBindValue( 3 );
q.addBindValue( values[ 3 ] );
QCOMPARE( q.boundValues().size(), 2 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 3 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[3] );
QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 3);
QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[3]);
QVERIFY_SQL( q, exec() );
QCOMPARE( q.boundValues().size(), 2 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 3 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[3] );
QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 3);
QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[3]);
q.addBindValue( 4 );
q.addBindValue( values[ 4 ] );
QCOMPARE( q.boundValues().size(), 2 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 4 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[4] );
QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 4);
QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[4]);
QVERIFY_SQL( q, exec() );
QCOMPARE( q.boundValues().size(), 2 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 4 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[4] );
QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 4);
QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[4]);
q.bindValue( 1, values[ 5 ] );
q.bindValue( 0, 5 );
QCOMPARE( q.boundValues().size(), 2 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 5 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[5] );
QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 5);
QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[5]);
QVERIFY_SQL( q, exec() );
QCOMPARE( q.boundValues().size(), 2 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 5 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[5] );
QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 5);
QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[5]);
q.bindValue( 0, 6 );
q.bindValue( 1, QString() );
QCOMPARE( q.boundValues().size(), 2 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 6 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), QString() );
QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 6);
QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), QString());
QVERIFY_SQL( q, exec() );
QCOMPARE( q.boundValues().size(), 2 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 6 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), QString() );
QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 6);
QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), QString());
if ( db.driver()->hasFeature( QSqlDriver::Unicode ) ) {
q.bindValue( 0, 7 );
q.bindValue( 1, utf8str );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 7 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), utf8str );
QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 7);
QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), utf8str);
QVERIFY_SQL( q, exec() );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 7 );
QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), utf8str );
QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 7);
QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), utf8str);
}
QVERIFY_SQL( q, exec( "SELECT * FROM " + qtest_prepare + " order by id" ) );