mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-22 00:06:12 -05:00
[wfs] Fix leak reading geometries
QgsWkbPtr does NOT take ownership of the data, port to QByteArray instead
This commit is contained in:
parent
76c767fe15
commit
3a893ace97
@ -797,21 +797,21 @@ void QgsGmlStreamingParser::startElement( const XML_Char *el, const XML_Char **a
|
||||
localNameLen == static_cast<int>( strlen( "Polygon" ) ) && memcmp( pszLocalName, "Polygon", localNameLen ) == 0 )
|
||||
{
|
||||
isGeom = true;
|
||||
mCurrentWKBFragments.push_back( QList<QgsWkbPtr>() );
|
||||
mCurrentWKBFragments.push_back( QList<QByteArray>() );
|
||||
}
|
||||
else if ( !mAttributeValIsNested && isGMLNS && LOCALNAME_EQUALS( "MultiPoint" ) )
|
||||
{
|
||||
isGeom = true;
|
||||
mParseModeStack.push( QgsGmlStreamingParser::MultiPoint );
|
||||
//we need one nested list for intermediate WKB
|
||||
mCurrentWKBFragments.push_back( QList<QgsWkbPtr>() );
|
||||
mCurrentWKBFragments.push_back( QList<QByteArray>() );
|
||||
}
|
||||
else if ( !mAttributeValIsNested && isGMLNS && ( LOCALNAME_EQUALS( "MultiLineString" ) || LOCALNAME_EQUALS( "MultiCurve" ) ) )
|
||||
{
|
||||
isGeom = true;
|
||||
mParseModeStack.push( QgsGmlStreamingParser::MultiLine );
|
||||
//we need one nested list for intermediate WKB
|
||||
mCurrentWKBFragments.push_back( QList<QgsWkbPtr>() );
|
||||
mCurrentWKBFragments.push_back( QList<QByteArray>() );
|
||||
}
|
||||
else if ( !mAttributeValIsNested && isGMLNS && ( LOCALNAME_EQUALS( "MultiPolygon" ) || LOCALNAME_EQUALS( "MultiSurface" ) ) )
|
||||
{
|
||||
@ -1241,9 +1241,9 @@ void QgsGmlStreamingParser::endElement( const XML_Char *el )
|
||||
if ( mCurrentWKB.size() > 0 )
|
||||
{
|
||||
QgsGeometry g;
|
||||
g.fromWkb( mCurrentWKB, mCurrentWKB.size() );
|
||||
g.fromWkb( mCurrentWKB );
|
||||
mCurrentFeature->setGeometry( g );
|
||||
mCurrentWKB = QgsWkbPtr( nullptr, 0 );
|
||||
mCurrentWKB = QByteArray();
|
||||
}
|
||||
else if ( !mCurrentExtent.isEmpty() )
|
||||
{
|
||||
@ -1292,7 +1292,7 @@ void QgsGmlStreamingParser::endElement( const XML_Char *el )
|
||||
}
|
||||
else //multipoint, add WKB as fragment
|
||||
{
|
||||
QgsWkbPtr wkbPtr( nullptr, 0 );
|
||||
QByteArray wkbPtr;
|
||||
if ( getPointWKB( wkbPtr, *( pointList.constBegin() ) ) != 0 )
|
||||
{
|
||||
//error
|
||||
@ -1304,7 +1304,6 @@ void QgsGmlStreamingParser::endElement( const XML_Char *el )
|
||||
else
|
||||
{
|
||||
QgsDebugError( QStringLiteral( "No wkb fragments" ) );
|
||||
delete [] wkbPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1332,7 +1331,7 @@ void QgsGmlStreamingParser::endElement( const XML_Char *el )
|
||||
}
|
||||
else //multiline, add WKB as fragment
|
||||
{
|
||||
QgsWkbPtr wkbPtr( nullptr, 0 );
|
||||
QByteArray wkbPtr;
|
||||
if ( getLineWKB( wkbPtr, pointList ) != 0 )
|
||||
{
|
||||
//error
|
||||
@ -1344,7 +1343,6 @@ void QgsGmlStreamingParser::endElement( const XML_Char *el )
|
||||
else
|
||||
{
|
||||
QgsDebugError( QStringLiteral( "no wkb fragments" ) );
|
||||
delete [] wkbPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1357,7 +1355,7 @@ void QgsGmlStreamingParser::endElement( const XML_Char *el )
|
||||
//error
|
||||
}
|
||||
|
||||
QgsWkbPtr wkbPtr( nullptr, 0 );
|
||||
QByteArray wkbPtr;
|
||||
if ( getRingWKB( wkbPtr, pointList ) != 0 )
|
||||
{
|
||||
//error
|
||||
@ -1369,7 +1367,6 @@ void QgsGmlStreamingParser::endElement( const XML_Char *el )
|
||||
}
|
||||
else
|
||||
{
|
||||
delete[] wkbPtr;
|
||||
QgsDebugError( QStringLiteral( "no wkb fragments" ) );
|
||||
}
|
||||
}
|
||||
@ -1661,10 +1658,10 @@ int QgsGmlStreamingParser::pointsFromString( QList<QgsPointXY> &points, const QS
|
||||
return 1;
|
||||
}
|
||||
|
||||
int QgsGmlStreamingParser::getPointWKB( QgsWkbPtr &wkbPtr, const QgsPointXY &point ) const
|
||||
int QgsGmlStreamingParser::getPointWKB( QByteArray &wkbPtr, const QgsPointXY &point ) const
|
||||
{
|
||||
const int wkbSize = 1 + sizeof( int ) + 2 * sizeof( double );
|
||||
wkbPtr = QgsWkbPtr( new unsigned char[wkbSize], wkbSize );
|
||||
wkbPtr = QByteArray( wkbSize, Qt::Uninitialized );
|
||||
|
||||
QgsWkbPtr fillPtr( wkbPtr );
|
||||
fillPtr << mEndian << Qgis::WkbType::Point << point.x() << point.y();
|
||||
@ -1672,10 +1669,10 @@ int QgsGmlStreamingParser::getPointWKB( QgsWkbPtr &wkbPtr, const QgsPointXY &poi
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QgsGmlStreamingParser::getLineWKB( QgsWkbPtr &wkbPtr, const QList<QgsPointXY> &lineCoordinates ) const
|
||||
int QgsGmlStreamingParser::getLineWKB( QByteArray &wkbPtr, const QList<QgsPointXY> &lineCoordinates ) const
|
||||
{
|
||||
const int wkbSize = 1 + 2 * sizeof( int ) + lineCoordinates.size() * 2 * sizeof( double );
|
||||
wkbPtr = QgsWkbPtr( new unsigned char[wkbSize], wkbSize );
|
||||
wkbPtr = QByteArray( wkbSize, Qt::Uninitialized );
|
||||
|
||||
QgsWkbPtr fillPtr( wkbPtr );
|
||||
|
||||
@ -1690,10 +1687,10 @@ int QgsGmlStreamingParser::getLineWKB( QgsWkbPtr &wkbPtr, const QList<QgsPointXY
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QgsGmlStreamingParser::getRingWKB( QgsWkbPtr &wkbPtr, const QList<QgsPointXY> &ringCoordinates ) const
|
||||
int QgsGmlStreamingParser::getRingWKB( QByteArray &wkbPtr, const QList<QgsPointXY> &ringCoordinates ) const
|
||||
{
|
||||
const int wkbSize = sizeof( int ) + ringCoordinates.size() * 2 * sizeof( double );
|
||||
wkbPtr = QgsWkbPtr( new unsigned char[wkbSize], wkbSize );
|
||||
wkbPtr = QByteArray( wkbSize, Qt::Uninitialized );
|
||||
|
||||
QgsWkbPtr fillPtr( wkbPtr );
|
||||
|
||||
@ -1711,19 +1708,18 @@ int QgsGmlStreamingParser::getRingWKB( QgsWkbPtr &wkbPtr, const QList<QgsPointXY
|
||||
int QgsGmlStreamingParser::createMultiLineFromFragments()
|
||||
{
|
||||
const int size = 1 + 2 * sizeof( int ) + totalWKBFragmentSize();
|
||||
mCurrentWKB = QgsWkbPtr( new unsigned char[size], size );
|
||||
mCurrentWKB = QByteArray( size, Qt::Uninitialized );
|
||||
|
||||
QgsWkbPtr wkbPtr( mCurrentWKB );
|
||||
|
||||
wkbPtr << mEndian << Qgis::WkbType::MultiLineString << mCurrentWKBFragments.constBegin()->size();
|
||||
|
||||
//copy (and delete) all the wkb fragments
|
||||
QList<QgsWkbPtr>::const_iterator wkbIt = mCurrentWKBFragments.constBegin()->constBegin();
|
||||
auto wkbIt = mCurrentWKBFragments.constBegin()->constBegin();
|
||||
for ( ; wkbIt != mCurrentWKBFragments.constBegin()->constEnd(); ++wkbIt )
|
||||
{
|
||||
memcpy( wkbPtr, *wkbIt, wkbIt->size() );
|
||||
wkbPtr += wkbIt->size();
|
||||
delete[] *wkbIt;
|
||||
}
|
||||
|
||||
mCurrentWKBFragments.clear();
|
||||
@ -1734,17 +1730,16 @@ int QgsGmlStreamingParser::createMultiLineFromFragments()
|
||||
int QgsGmlStreamingParser::createMultiPointFromFragments()
|
||||
{
|
||||
const int size = 1 + 2 * sizeof( int ) + totalWKBFragmentSize();
|
||||
mCurrentWKB = QgsWkbPtr( new unsigned char[size], size );
|
||||
mCurrentWKB = QByteArray( size, Qt::Uninitialized );
|
||||
|
||||
QgsWkbPtr wkbPtr( mCurrentWKB );
|
||||
wkbPtr << mEndian << Qgis::WkbType::MultiPoint << mCurrentWKBFragments.constBegin()->size();
|
||||
|
||||
QList<QgsWkbPtr>::const_iterator wkbIt = mCurrentWKBFragments.constBegin()->constBegin();
|
||||
auto wkbIt = mCurrentWKBFragments.constBegin()->constBegin();
|
||||
for ( ; wkbIt != mCurrentWKBFragments.constBegin()->constEnd(); ++wkbIt )
|
||||
{
|
||||
memcpy( wkbPtr, *wkbIt, wkbIt->size() );
|
||||
wkbPtr += wkbIt->size();
|
||||
delete[] *wkbIt;
|
||||
}
|
||||
|
||||
mCurrentWKBFragments.clear();
|
||||
@ -1756,17 +1751,16 @@ int QgsGmlStreamingParser::createMultiPointFromFragments()
|
||||
int QgsGmlStreamingParser::createPolygonFromFragments()
|
||||
{
|
||||
const int size = 1 + 2 * sizeof( int ) + totalWKBFragmentSize();
|
||||
mCurrentWKB = QgsWkbPtr( new unsigned char[size], size );
|
||||
mCurrentWKB = QByteArray( size, Qt::Uninitialized );
|
||||
|
||||
QgsWkbPtr wkbPtr( mCurrentWKB );
|
||||
wkbPtr << mEndian << Qgis::WkbType::Polygon << mCurrentWKBFragments.constBegin()->size();
|
||||
|
||||
QList<QgsWkbPtr>::const_iterator wkbIt = mCurrentWKBFragments.constBegin()->constBegin();
|
||||
auto wkbIt = mCurrentWKBFragments.constBegin()->constBegin();
|
||||
for ( ; wkbIt != mCurrentWKBFragments.constBegin()->constEnd(); ++wkbIt )
|
||||
{
|
||||
memcpy( wkbPtr, *wkbIt, wkbIt->size() );
|
||||
wkbPtr += wkbIt->size();
|
||||
delete[] *wkbIt;
|
||||
}
|
||||
|
||||
mCurrentWKBFragments.clear();
|
||||
@ -1781,25 +1775,24 @@ int QgsGmlStreamingParser::createMultiPolygonFromFragments()
|
||||
size += totalWKBFragmentSize();
|
||||
size += mCurrentWKBFragments.size() * ( 1 + 2 * sizeof( int ) ); //fragments are just the rings
|
||||
|
||||
mCurrentWKB = QgsWkbPtr( new unsigned char[size], size );
|
||||
mCurrentWKB = QByteArray( size, Qt::Uninitialized );
|
||||
|
||||
QgsWkbPtr wkbPtr( mCurrentWKB );
|
||||
wkbPtr << ( char ) mEndian << Qgis::WkbType::MultiPolygon << mCurrentWKBFragments.size();
|
||||
|
||||
//have outer and inner iterators
|
||||
QList< QList<QgsWkbPtr> >::const_iterator outerWkbIt = mCurrentWKBFragments.constBegin();
|
||||
auto outerWkbIt = mCurrentWKBFragments.constBegin();
|
||||
|
||||
for ( ; outerWkbIt != mCurrentWKBFragments.constEnd(); ++outerWkbIt )
|
||||
{
|
||||
//new polygon
|
||||
wkbPtr << ( char ) mEndian << Qgis::WkbType::Polygon << outerWkbIt->size();
|
||||
|
||||
QList<QgsWkbPtr>::const_iterator innerWkbIt = outerWkbIt->constBegin();
|
||||
auto innerWkbIt = outerWkbIt->constBegin();
|
||||
for ( ; innerWkbIt != outerWkbIt->constEnd(); ++innerWkbIt )
|
||||
{
|
||||
memcpy( wkbPtr, *innerWkbIt, innerWkbIt->size() );
|
||||
wkbPtr += innerWkbIt->size();
|
||||
delete[] *innerWkbIt;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1811,11 +1804,9 @@ int QgsGmlStreamingParser::createMultiPolygonFromFragments()
|
||||
int QgsGmlStreamingParser::totalWKBFragmentSize() const
|
||||
{
|
||||
int result = 0;
|
||||
const auto constMCurrentWKBFragments = mCurrentWKBFragments;
|
||||
for ( const QList<QgsWkbPtr> &list : constMCurrentWKBFragments )
|
||||
for ( const QList<QByteArray> &list : std::as_const( mCurrentWKBFragments ) )
|
||||
{
|
||||
const auto constList = list;
|
||||
for ( const QgsWkbPtr &i : constList )
|
||||
for ( const QByteArray &i : list )
|
||||
{
|
||||
result += i.size();
|
||||
}
|
||||
|
@ -244,9 +244,9 @@ class CORE_EXPORT QgsGmlStreamingParser
|
||||
int pointsFromPosListString( QList<QgsPointXY> &points, const QString &coordString, int dimension ) const;
|
||||
|
||||
int pointsFromString( QList<QgsPointXY> &points, const QString &coordString ) const;
|
||||
int getPointWKB( QgsWkbPtr &wkbPtr, const QgsPointXY & ) const;
|
||||
int getLineWKB( QgsWkbPtr &wkbPtr, const QList<QgsPointXY> &lineCoordinates ) const;
|
||||
int getRingWKB( QgsWkbPtr &wkbPtr, const QList<QgsPointXY> &ringCoordinates ) const;
|
||||
int getPointWKB( QByteArray &wkbPtr, const QgsPointXY & ) const;
|
||||
int getLineWKB( QByteArray &wkbPtr, const QList<QgsPointXY> &lineCoordinates ) const;
|
||||
int getRingWKB( QByteArray &wkbPtr, const QList<QgsPointXY> &ringCoordinates ) const;
|
||||
|
||||
/**
|
||||
* Creates a multiline from the information in mCurrentWKBFragments and
|
||||
@ -318,7 +318,7 @@ class CORE_EXPORT QgsGmlStreamingParser
|
||||
QString mCurrentFeatureId;
|
||||
int mFeatureCount;
|
||||
//! The total WKB for a feature
|
||||
QgsWkbPtr mCurrentWKB;
|
||||
QByteArray mCurrentWKB;
|
||||
QgsRectangle mCurrentExtent;
|
||||
bool mBoundedByNullFound;
|
||||
|
||||
@ -328,7 +328,7 @@ class CORE_EXPORT QgsGmlStreamingParser
|
||||
* polygons, only one nested list is used. For multipolygons, both nested lists
|
||||
* are used
|
||||
*/
|
||||
QList< QList<QgsWkbPtr> > mCurrentWKBFragments;
|
||||
QList< QList< QByteArray > > mCurrentWKBFragments;
|
||||
QString mAttributeName;
|
||||
int mAttributeDepth = -1;
|
||||
bool mAttributeValIsNested = false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user