fix(qgssfcgalengine): Fix memory leak in toWkb method

This commit is contained in:
Jean Felder 2025-09-03 15:33:22 +02:00 committed by Nyall Dawson
parent 3b5e5c6039
commit c07bbfbd56
3 changed files with 20 additions and 13 deletions

View File

@ -303,16 +303,16 @@ std::unique_ptr<QgsAbstractGeometry> QgsSfcgalEngine::toAbstractGeometry( const
sfcgal::errorHandler()->clearText( errorMsg ); sfcgal::errorHandler()->clearText( errorMsg );
CHECK_NOT_NULL( geom, out ); CHECK_NOT_NULL( geom, out );
QgsConstWkbPtr ptr = QgsSfcgalEngine::toWkb( geom, errorMsg ); QByteArray wkbArray = QgsSfcgalEngine::toWkb( geom, errorMsg );
CHECK_SUCCESS( errorMsg, out ); CHECK_SUCCESS( errorMsg, out );
out = QgsGeometryFactory::geomFromWkb( ptr ); QgsConstWkbPtr wkbPtr( wkbArray );
out = QgsGeometryFactory::geomFromWkb( wkbPtr );
if ( !out ) if ( !out )
{ {
Qgis::WkbType sfcgalType = QgsSfcgalEngine::wkbType( geom ); Qgis::WkbType sfcgalType = QgsSfcgalEngine::wkbType( geom );
QgsConstWkbPtr ptrError = QgsSfcgalEngine::toWkb( geom );
sfcgal::errorHandler()->addText( QStringLiteral( "WKB contains unmanaged geometry type (WKB:%1 / SFCGAL:%2" ) // sfcgal::errorHandler()->addText( QStringLiteral( "WKB contains unmanaged geometry type (WKB:%1 / SFCGAL:%2" ) //
.arg( static_cast<int>( ptrError.readHeader() ) ) // .arg( static_cast<int>( wkbPtr.readHeader() ) ) //
.arg( static_cast<int>( sfcgalType ) ), .arg( static_cast<int>( sfcgalType ) ),
__FILE__, __FUNCTION__, __LINE__ ); __FILE__, __FUNCTION__, __LINE__ );
} }
@ -380,17 +380,24 @@ sfcgal::shared_geom QgsSfcgalEngine::fromWkt( const QString &wkt, QString *error
return sfcgal::unique_geom( out ); return sfcgal::unique_geom( out );
} }
QgsConstWkbPtr QgsSfcgalEngine::toWkb( const sfcgal::geometry *geom, QString *errorMsg ) QByteArray QgsSfcgalEngine::toWkb( const sfcgal::geometry *geom, QString *errorMsg )
{ {
sfcgal::errorHandler()->clearText( errorMsg ); sfcgal::errorHandler()->clearText( errorMsg );
CHECK_NOT_NULL( geom, QgsConstWkbPtr( nullptr, 0 ) ); CHECK_NOT_NULL( geom, QByteArray() );
char *wkbHex; char *wkbHex;
size_t len = 0; size_t len = 0;
sfcgal_geometry_as_wkb( geom, &wkbHex, &len ); sfcgal_geometry_as_wkb( geom, &wkbHex, &len );
CHECK_SUCCESS( errorMsg, QgsConstWkbPtr( nullptr, 0 ) ); QByteArray wkbArray( wkbHex, static_cast<int>( len ) );
return QgsConstWkbPtr( reinterpret_cast<unsigned char *>( wkbHex ), static_cast<int>( len ) ); #if SFCGAL_VERSION_MAJOR_INT > 2 || ( SFCGAL_VERSION_MAJOR_INT == 2 && SFCGAL_VERSION_MINOR_INT >= 1 )
sfcgal_free_buffer( wkbHex );
#else
free( wkbHex );
#endif
CHECK_SUCCESS( errorMsg, QByteArray() );
return wkbArray;
} }
QString QgsSfcgalEngine::toWkt( const sfcgal::geometry *geom, int numDecimals, QString *errorMsg ) QString QgsSfcgalEngine::toWkt( const sfcgal::geometry *geom, int numDecimals, QString *errorMsg )
@ -685,7 +692,8 @@ QgsPoint QgsSfcgalEngine::centroid( const sfcgal::geometry *geom, QString *error
CHECK_SUCCESS( errorMsg, QgsPoint() ); CHECK_SUCCESS( errorMsg, QgsPoint() );
CHECK_NOT_NULL( result, QgsPoint() ); CHECK_NOT_NULL( result, QgsPoint() );
QgsConstWkbPtr wkbPtr = QgsSfcgalEngine::toWkb( result, errorMsg ); QByteArray wkbArray = QgsSfcgalEngine::toWkb( result, errorMsg );
QgsConstWkbPtr wkbPtr( wkbArray );
QgsPoint out; QgsPoint out;
out.fromWkb( wkbPtr ); out.fromWkb( wkbPtr );

View File

@ -220,7 +220,7 @@ class CORE_EXPORT QgsSfcgalEngine
* \param geom geometry to perform the operation * \param geom geometry to perform the operation
* \param errorMsg Error message returned by SFGCAL * \param errorMsg Error message returned by SFGCAL
*/ */
static QgsConstWkbPtr toWkb( const sfcgal::geometry *geom, QString *errorMsg = nullptr ); static QByteArray toWkb( const sfcgal::geometry *geom, QString *errorMsg = nullptr );
/** /**
* Computes WKT string from \a geom. * Computes WKT string from \a geom.

View File

@ -127,11 +127,10 @@ std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::fromWkb( const QgsConstWkb
QByteArray QgsSfcgalGeometry::asWkb( QgsAbstractGeometry::WkbFlags ) const QByteArray QgsSfcgalGeometry::asWkb( QgsAbstractGeometry::WkbFlags ) const
{ {
sfcgal::errorHandler()->clearText( &mLastError ); sfcgal::errorHandler()->clearText( &mLastError );
QgsConstWkbPtr ptr = QgsSfcgalEngine::toWkb( mSfcgalGeom.get(), &mLastError ); QByteArray wkbArray = QgsSfcgalEngine::toWkb( mSfcgalGeom.get(), &mLastError );
CHECK_SUCCESS( &mLastError, QByteArray() ); CHECK_SUCCESS( &mLastError, QByteArray() );
const unsigned char *wkbUnsignedPtr = ptr; return wkbArray;
return QByteArray( reinterpret_cast<const char *>( wkbUnsignedPtr ), ptr.remaining() );
} }
QString QgsSfcgalGeometry::asWkt( int precision ) const QString QgsSfcgalGeometry::asWkt( int precision ) const