Details
-
Bug
-
Resolution: Fixed
-
P2: Important
-
5.7, 5.13.1
-
Windows 8.1 and 10 using Visual Studio 2013.5
Description
The Postgres SQL plugin leaks memory under a specific situation. The whole thing takes place in qsql_psql.cpp:1543, QPSQLDriver::formatValue.
The Postgres SQL plugin converts QByteArray to QString when executing a query. During the conversion special characters in the QByteArray are escaped using the function PQescapeByteaConn or PQescapeBytea from libpq. The result of either function is stored at a char array, the pointer then passed to the QLatin1String constructor. After successfully creating the QString, the memory at the pointer gets freed. If the construction of the QString fails, the memory at the pointer is not freed at all.
Construction of the QString can fail, if the QByteArray is too large: QString and QByteArray allow for 2GB of data but Postgres' escape functions might add extra characters, resulting in fewer bytes one can savely provide when executing a query. On Windows platforms (VS2013) an std::bad_alloc exception is thrown, which is not caught by the Postgres SQL plugin, leaving the converted bytes unfreed (possible several hundert megabytes). The query is not executed and the calling function doesn't have a chance to free the escaped bytes.
Our proposal is to catch any exception, free the escaped bytes and rethrow the exception. A patch is attached and a MWE, too.
We didn't test this behaviour and patch on other platforms or compilers than Windows 8.1, 10 and Visual Studio 2013.
The memory leak is present in dev and all versions from at least 5.7 on.
Attachments
For Gerrit Dashboard: QTBUG-79059 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
276954,4 | Fix a potential memory leak in the PostgreSQL plugin | 5.13 | qt/qtbase | Status: ABANDONED | -1 | 0 |
330396,2 | QSql/PostgreSQL: allow blobs with more than 2^30 bytes | dev | qt/qtbase | Status: MERGED | +2 | 0 |
331254,2 | QSql/PostgreSQL: allow blobs with more than 2^30 bytes | 6.0 | qt/qtbase | Status: MERGED | +2 | 0 |