Skip to content

Commit d8ca919

Browse files
committed
fix crashes using uninitialized geometries with GEOS functions,
ensure geos geometries are up to date when passed to GEOS functions
1 parent cde8b1e commit d8ca919

File tree

1 file changed

+102
-46
lines changed

1 file changed

+102
-46
lines changed

src/core/qgsgeometry.cpp

Lines changed: 102 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2978,8 +2978,15 @@ double QgsGeometry::closestVertexWithContext( const QgsPoint& point, int& atVert
29782978
int closestVertexIndex = 0;
29792979

29802980
// set up the GEOS geometry
2981-
if ( !exportWkbToGeos() )
2982-
return -1;
2981+
if ( mDirtyGeos )
2982+
{
2983+
exportWkbToGeos();
2984+
}
2985+
2986+
if ( !mGeos )
2987+
{
2988+
return -1;
2989+
}
29832990

29842991
const GEOSGeometry *g = GEOSGetExteriorRing( mGeos );
29852992
if ( !g )
@@ -3276,9 +3283,15 @@ int QgsGeometry::addRing( const QList<QgsPoint>& ring )
32763283
return 2;
32773284

32783285
//create geos geometry from wkb if not already there
3279-
if ( !mGeos || mDirtyGeos )
3280-
if ( !exportWkbToGeos() )
3286+
if ( mDirtyGeos )
3287+
{
3288+
exportWkbToGeos();
3289+
}
3290+
3291+
if ( !mGeos )
3292+
{
32813293
return 6;
3294+
}
32823295

32833296
int type = GEOSGeomTypeId( mGeos );
32843297

@@ -3505,13 +3518,15 @@ int QgsGeometry::addPart( const QList<QgsPoint> &points )
35053518
}
35063519

35073520
//create geos geometry from wkb if not already there
3508-
if ( !mGeos || mDirtyGeos )
3521+
if ( mDirtyGeos )
35093522
{
3510-
if ( !exportWkbToGeos() )
3511-
{
3512-
QgsDebugMsg( "could not export to GEOS geometry" );
3513-
return 4;
3514-
}
3523+
exportWkbToGeos();
3524+
}
3525+
3526+
if ( !mGeos )
3527+
{
3528+
QgsDebugMsg( "GEOS geometry not available!" );
3529+
return 4;
35153530
}
35163531

35173532
int geosType = GEOSGeomTypeId( mGeos );
@@ -3881,10 +3896,14 @@ int QgsGeometry::splitGeometry( const QList<QgsPoint>& splitLine, QList<QgsGeome
38813896
exportGeosToWkb();
38823897
}
38833898

3884-
if ( !mGeos || mDirtyGeos )
3899+
if ( mDirtyGeos )
3900+
{
3901+
exportWkbToGeos();
3902+
}
3903+
3904+
if ( !mGeos )
38853905
{
3886-
if ( !exportWkbToGeos() )
3887-
return 1;
3906+
return 1;
38883907
}
38893908

38903909
if ( !GEOSisValid( mGeos ) )
@@ -3955,11 +3974,16 @@ int QgsGeometry::reshapeGeometry( const QList<QgsPoint>& reshapeWithLine )
39553974
GEOSGeometry* reshapeLineGeos = createGeosLineString( reshapeWithLine.toVector() );
39563975

39573976
//make sure this geos geometry is up-to-date
3958-
if ( !mGeos || mDirtyGeos )
3977+
if ( mDirtyGeos )
39593978
{
39603979
exportWkbToGeos();
39613980
}
39623981

3982+
if ( !mGeos )
3983+
{
3984+
return 1;
3985+
}
3986+
39633987
//single or multi?
39643988
int numGeoms = GEOSGetNumGeometries( mGeos );
39653989
if ( numGeoms == -1 )
@@ -4067,7 +4091,7 @@ int QgsGeometry::reshapeGeometry( const QList<QgsPoint>& reshapeWithLine )
40674091
int QgsGeometry::makeDifference( QgsGeometry* other )
40684092
{
40694093
//make sure geos geometry is up to date
4070-
if ( !mGeos || mDirtyGeos )
4094+
if ( mDirtyGeos )
40714095
{
40724096
exportWkbToGeos();
40734097
}
@@ -4088,7 +4112,7 @@ int QgsGeometry::makeDifference( QgsGeometry* other )
40884112
}
40894113

40904114
//convert other geometry to geos
4091-
if ( !other->mGeos || other->mDirtyGeos )
4115+
if ( other->mDirtyGeos )
40924116
{
40934117
other->exportWkbToGeos();
40944118
}
@@ -4161,6 +4185,7 @@ QgsRectangle QgsGeometry::boundingBox()
41614185
QgsDebugMsg( "WKB geometry not available!" );
41624186
return QgsRectangle( 0, 0, 0, 0 );
41634187
}
4188+
41644189
// consider endian when fetching feature type
41654190
//wkbType = (mGeometry[0] == 1) ? mGeometry[1] : mGeometry[4]; //MH: Does not work for 25D geometries
41664191
memcpy( &wkbType, &( mGeometry[1] ), sizeof( int ) );
@@ -6173,10 +6198,14 @@ int QgsGeometry::splitLinearGeometry( GEOSGeometry *splitLine, QList<QgsGeometry
61736198
return 2;
61746199
}
61756200

6176-
if ( !mGeos || mDirtyGeos )
6201+
if ( mDirtyGeos )
61776202
{
6178-
if ( !exportWkbToGeos() )
6179-
return 5;
6203+
exportWkbToGeos();
6204+
}
6205+
6206+
if ( !mGeos )
6207+
{
6208+
return 5;
61806209
}
61816210

61826211
//first test if linestring intersects geometry. If not, return straight away
@@ -6234,10 +6263,14 @@ int QgsGeometry::splitPolygonGeometry( GEOSGeometry* splitLine, QList<QgsGeometr
62346263
return 2;
62356264
}
62366265

6237-
if ( !mGeos || mDirtyGeos )
6266+
if ( mDirtyGeos )
62386267
{
6239-
if ( !exportWkbToGeos() )
6240-
return 5;
6268+
exportWkbToGeos();
6269+
}
6270+
6271+
if ( !mGeos )
6272+
{
6273+
return 5;
62416274
}
62426275

62436276
//first test if linestring intersects geometry. If not, return straight away
@@ -6939,10 +6972,14 @@ int QgsGeometry::numberOfGeometries( GEOSGeometry* g ) const
69396972

69406973
int QgsGeometry::mergeGeometriesMultiTypeSplit( QVector<GEOSGeometry*>& splitResult )
69416974
{
6942-
if ( !mGeos || mDirtyGeos )
6975+
if ( mDirtyGeos )
69436976
{
6944-
if ( !exportWkbToGeos() )
6945-
return 1;
6977+
exportWkbToGeos();
6978+
}
6979+
6980+
if ( !mGeos )
6981+
{
6982+
return 1;
69466983
}
69476984

69486985
//convert mGeos to geometry collection
@@ -7198,10 +7235,14 @@ QgsMultiPolygon QgsGeometry::asMultiPolygon()
71987235

71997236
double QgsGeometry::area()
72007237
{
7201-
if ( !mGeos )
7238+
if ( mDirtyGeos )
72027239
{
72037240
exportWkbToGeos();
72047241
}
7242+
if ( !mGeos )
7243+
{
7244+
return -1.0;
7245+
}
72057246

72067247
double area;
72077248

@@ -7217,10 +7258,14 @@ double QgsGeometry::area()
72177258

72187259
double QgsGeometry::length()
72197260
{
7220-
if ( !mGeos )
7261+
if ( mDirtyGeos )
72217262
{
72227263
exportWkbToGeos();
72237264
}
7265+
if ( !mGeos )
7266+
{
7267+
return -1.0;
7268+
}
72247269

72257270
double length;
72267271

@@ -7235,12 +7280,11 @@ double QgsGeometry::length()
72357280
}
72367281
double QgsGeometry::distance( QgsGeometry& geom )
72377282
{
7238-
if ( !mGeos )
7283+
if ( mDirtyGeos )
72397284
{
72407285
exportWkbToGeos();
72417286
}
7242-
7243-
if ( !geom.mGeos )
7287+
if ( geom.mDirtyGeos )
72447288
{
72457289
geom.exportWkbToGeos();
72467290
}
@@ -7262,7 +7306,7 @@ double QgsGeometry::distance( QgsGeometry& geom )
72627306

72637307
QgsGeometry* QgsGeometry::buffer( double distance, int segments )
72647308
{
7265-
if ( !mGeos )
7309+
if ( mDirtyGeos )
72667310
{
72677311
exportWkbToGeos();
72687312
}
@@ -7280,7 +7324,7 @@ QgsGeometry* QgsGeometry::buffer( double distance, int segments )
72807324

72817325
QgsGeometry* QgsGeometry::simplify( double tolerance )
72827326
{
7283-
if ( !mGeos )
7327+
if ( mDirtyGeos )
72847328
{
72857329
exportWkbToGeos();
72867330
}
@@ -7297,7 +7341,7 @@ QgsGeometry* QgsGeometry::simplify( double tolerance )
72977341

72987342
QgsGeometry* QgsGeometry::centroid()
72997343
{
7300-
if ( !mGeos )
7344+
if ( mDirtyGeos )
73017345
{
73027346
exportWkbToGeos();
73037347
}
@@ -7314,7 +7358,7 @@ QgsGeometry* QgsGeometry::centroid()
73147358

73157359
QgsGeometry* QgsGeometry::convexHull()
73167360
{
7317-
if ( !mGeos )
7361+
if ( mDirtyGeos )
73187362
{
73197363
exportWkbToGeos();
73207364
}
@@ -7334,7 +7378,7 @@ QgsGeometry* QgsGeometry::interpolate( double distance )
73347378
{
73357379
#if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
73367380
((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=2)))
7337-
if ( !mGeos )
7381+
if ( mDirtyGeos )
73387382
{
73397383
exportWkbToGeos();
73407384
}
@@ -7359,14 +7403,17 @@ QgsGeometry* QgsGeometry::intersection( QgsGeometry* geometry )
73597403
{
73607404
return NULL;
73617405
}
7362-
if ( !mGeos )
7406+
7407+
if ( mDirtyGeos )
73637408
{
73647409
exportWkbToGeos();
73657410
}
7366-
if ( !geometry->mGeos )
7411+
if ( geometry->mDirtyGeos )
73677412
{
73687413
geometry->exportWkbToGeos();
73697414
}
7415+
7416+
73707417
if ( !mGeos || !geometry->mGeos )
73717418
{
73727419
return 0;
@@ -7385,14 +7432,16 @@ QgsGeometry* QgsGeometry::combine( QgsGeometry* geometry )
73857432
{
73867433
return NULL;
73877434
}
7388-
if ( !mGeos )
7435+
7436+
if ( mDirtyGeos )
73897437
{
73907438
exportWkbToGeos();
73917439
}
7392-
if ( !geometry->mGeos )
7440+
if ( geometry->mDirtyGeos )
73937441
{
73947442
geometry->exportWkbToGeos();
73957443
}
7444+
73967445
if ( !mGeos || !geometry->mGeos )
73977446
{
73987447
return 0;
@@ -7421,14 +7470,16 @@ QgsGeometry* QgsGeometry::difference( QgsGeometry* geometry )
74217470
{
74227471
return NULL;
74237472
}
7424-
if ( !mGeos )
7473+
7474+
if ( mDirtyGeos )
74257475
{
74267476
exportWkbToGeos();
74277477
}
7428-
if ( !geometry->mGeos )
7478+
if ( geometry->mDirtyGeos )
74297479
{
74307480
geometry->exportWkbToGeos();
74317481
}
7482+
74327483
if ( !mGeos || !geometry->mGeos )
74337484
{
74347485
return 0;
@@ -7447,14 +7498,16 @@ QgsGeometry* QgsGeometry::symDifference( QgsGeometry* geometry )
74477498
{
74487499
return NULL;
74497500
}
7450-
if ( !mGeos )
7501+
7502+
if ( mDirtyGeos )
74517503
{
74527504
exportWkbToGeos();
74537505
}
7454-
if ( !geometry->mGeos )
7506+
if ( geometry->mDirtyGeos )
74557507
{
74567508
geometry->exportWkbToGeos();
74577509
}
7510+
74587511
if ( !mGeos || !geometry->mGeos )
74597512
{
74607513
return 0;
@@ -7469,11 +7522,14 @@ QgsGeometry* QgsGeometry::symDifference( QgsGeometry* geometry )
74697522

74707523
QList<QgsGeometry*> QgsGeometry::asGeometryCollection()
74717524
{
7472-
if ( !mGeos )
7525+
if ( mDirtyGeos )
74737526
{
74747527
exportWkbToGeos();
7475-
if ( !mGeos )
7476-
return QList<QgsGeometry*>();
7528+
}
7529+
7530+
if ( !mGeos )
7531+
{
7532+
return QList<QgsGeometry*>();
74777533
}
74787534

74797535
int type = GEOSGeomTypeId( mGeos );

0 commit comments

Comments
 (0)