Skip to content
Permalink
Browse files

When creating geometry collections for GEOS, skip any empty parts

These can cause crashes in GEOS functions

Fixes #37688
  • Loading branch information
nyalldawson committed Jul 9, 2020
1 parent caff652 commit 6ddff0def89a78ee9567ab3d01b1ae180f92cd35
Showing with 33 additions and 2 deletions.
  1. +12 −2 src/core/geometry/qgsgeos.cpp
  2. +21 −0 tests/src/core/testqgsgeometry.cpp
@@ -1055,8 +1055,18 @@ geos::unique_ptr QgsGeos::createGeosCollection( int typeId, const QVector<GEOSGe
{
if ( *geomIt )
{
geomarr[i] = *geomIt;
++i;
if ( GEOSisEmpty_r( geosinit()->ctxt, *geomIt ) )
{
// don't add empty parts to a geos collection, it can cause crashes in GEOS
nNullGeoms++;
nNotNullGeoms--;
GEOSGeom_destroy_r( geosinit()->ctxt, *geomIt );
}
else
{
geomarr[i] = *geomIt;
++i;
}
}
}
geos::unique_ptr geom;
@@ -52,6 +52,7 @@
#include "qgscurvepolygon.h"
#include "qgsproject.h"
#include "qgslinesegment.h"
#include "qgsgeos.h"

//qgs unit test utility class
#include "qgsrenderchecker.h"
@@ -85,6 +86,7 @@ class TestQgsGeometry : public QObject
void vertexIterator();
void partIterator();

void geos();

// geometry types
void point(); //test QgsPointV2
@@ -522,6 +524,25 @@ void TestQgsGeometry::partIterator()
// See test_qgsgeometry.py for geometry-type specific checks!
}

void TestQgsGeometry::geos()
{
// test GEOS conversion utils

// empty parts should NOT be added to a GEOS collection -- it can cause crashes in GEOS
QgsMultiPolygon polyWithEmptyParts;
geos::unique_ptr asGeos( QgsGeos::asGeos( &polyWithEmptyParts ) );
QgsGeometry res( QgsGeos::fromGeos( asGeos.get() ) );
QCOMPARE( res.asWkt(), QStringLiteral( "MultiPolygon EMPTY" ) );
polyWithEmptyParts.addGeometry( new QgsPolygon( new QgsLineString() ) );
polyWithEmptyParts.addGeometry( new QgsPolygon( new QgsLineString( QVector< QgsPoint >() << QgsPoint( 0, 0 ) << QgsPoint( 0, 1 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 0 ) ) ) );
polyWithEmptyParts.addGeometry( new QgsPolygon( new QgsLineString() ) );
polyWithEmptyParts.addGeometry( new QgsPolygon( new QgsLineString( QVector< QgsPoint >() << QgsPoint( 10, 0 ) << QgsPoint( 10, 1 ) << QgsPoint( 11, 1 ) << QgsPoint( 10, 0 ) ) ) );
asGeos = QgsGeos::asGeos( &polyWithEmptyParts );
QCOMPARE( GEOSGetNumGeometries_r( QgsGeos::getGEOSHandler(), asGeos.get() ), 2 );
res = QgsGeometry( QgsGeos::fromGeos( asGeos.get() ) );
QCOMPARE( res.asWkt(), QStringLiteral( "MultiPolygon (((0 0, 0 1, 1 1, 0 0)),((10 0, 10 1, 11 1, 10 0)))" ) );
}

void TestQgsGeometry::point()
{
//test QgsPointV2

0 comments on commit 6ddff0d

Please sign in to comment.
You can’t perform that action at this time.