[Development] QString, QVariant and QSQLite

Henry Skoglund henry at tungware.se
Wed May 26 21:48:53 CEST 2021

On 2021-05-26 21:39, Alberto Mardegan wrote:
> Hi there!
>    I'm encountering some sort of memory corruption issue in a library I'm
> using, which does not cause a crash, but rather a QSQLite query to
> sometimes simply return no results, without errors or warnings.
> You can find the valgrind trace here:
> https://git.sailfishos.org/mer-core/qtcontacts-sqlite/issues/7#note_90394
> What is happening is that we bind a couple of SQLite parameters to a
> prepared query. The first bound parameter is a QString.
> 1) The string is stored into a QVariant
> 2) QSqlQuery::bindValue() is called
> 3) in the sqlite plugin, the qvariant is copied into a const QVariant:
> https://code.qt.io/cgit/qt/qtbase.git/tree/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp?h=5.12#n503
> 4) in line 539 of the SQLite plugin, the contents of the QVariant are
> obtained just by calling QString::utf16() on the string data, without
> extracting it from the QVariant.
> 5) the data is passed to sqlite with SQLITE_STATIC (sqlite will NOT copy it)
> 6) we move forward and iterate to the next bound parameter
> 7) our const QVariant goes out of scope (though valgrind shows that the
> destructor is actually called on the next iteration of the for loop --
> but I guess this is not fundamental)
> 8) the destructor of the const QVariant calls the destructor of the
> QString stored in it, which frees the memory allocated in point 4 by
> QString::utf16()
> Now, I haven't dug very deep in QString and QVariant, I preferred to let
> the experts talk first :-) Does the code in the QSQLite plugin look
> correct to you?
> Is it expected that QString::utf16() makes a memory allocation? And is
> it correct that this happens even when the QString is const?
> And why destroying a const QVariant causes the deallocation of the data
> created by QString::utf16()??
> The most plausible explanation is that I have some memory corruption
> somewhere else in the program, but I find it curious that it never
> crashes the program and that it manifests itself always in this code
> path. Notice also that if I call QString::detach() on my parameter
> before storing it into the QVariant I pass to QSqlQuery::bindValue(),
> then valgrind never complains and QSQLite returns the expected results.
> Or do you think it could be a bug in the QSQLite plugin?
> Ciao,
>    Alberto
Hi, as a first quick test, if instead of using the binding mechanism, 
you use sprintf() or QString(..%1 .. %2).arg() etc. to construct your 
query string. Does your memory corruptions still occur?
(Note: this is not recommened since it allows SQL injection or similar 
bad things, but you could try it as a test.)

More information about the Development mailing list