Skip to content

Commit

Permalink
fix crashes using uninitialized geometries with GEOS functions,
Browse files Browse the repository at this point in the history
ensure geos geometries are up to date when passed to GEOS functions
  • Loading branch information
brushtyler committed Nov 2, 2012
1 parent cde8b1e commit d8ca919
Showing 1 changed file with 102 additions and 46 deletions.
148 changes: 102 additions & 46 deletions src/core/qgsgeometry.cpp
Expand Up @@ -2978,8 +2978,15 @@ double QgsGeometry::closestVertexWithContext( const QgsPoint& point, int& atVert
int closestVertexIndex = 0;

// set up the GEOS geometry
if ( !exportWkbToGeos() )
return -1;
if ( mDirtyGeos )
{
exportWkbToGeos();
}

if ( !mGeos )
{
return -1;
}

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

//create geos geometry from wkb if not already there
if ( !mGeos || mDirtyGeos )
if ( !exportWkbToGeos() )
if ( mDirtyGeos )
{
exportWkbToGeos();
}

if ( !mGeos )
{
return 6;
}

int type = GEOSGeomTypeId( mGeos );

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

//create geos geometry from wkb if not already there
if ( !mGeos || mDirtyGeos )
if ( mDirtyGeos )
{
if ( !exportWkbToGeos() )
{
QgsDebugMsg( "could not export to GEOS geometry" );
return 4;
}
exportWkbToGeos();
}

if ( !mGeos )
{
QgsDebugMsg( "GEOS geometry not available!" );
return 4;
}

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

if ( !mGeos || mDirtyGeos )
if ( mDirtyGeos )
{
exportWkbToGeos();
}

if ( !mGeos )
{
if ( !exportWkbToGeos() )
return 1;
return 1;
}

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

//make sure this geos geometry is up-to-date
if ( !mGeos || mDirtyGeos )
if ( mDirtyGeos )
{
exportWkbToGeos();
}

if ( !mGeos )
{
return 1;
}

//single or multi?
int numGeoms = GEOSGetNumGeometries( mGeos );
if ( numGeoms == -1 )
Expand Down Expand Up @@ -4067,7 +4091,7 @@ int QgsGeometry::reshapeGeometry( const QList<QgsPoint>& reshapeWithLine )
int QgsGeometry::makeDifference( QgsGeometry* other )
{
//make sure geos geometry is up to date
if ( !mGeos || mDirtyGeos )
if ( mDirtyGeos )
{
exportWkbToGeos();
}
Expand All @@ -4088,7 +4112,7 @@ int QgsGeometry::makeDifference( QgsGeometry* other )
}

//convert other geometry to geos
if ( !other->mGeos || other->mDirtyGeos )
if ( other->mDirtyGeos )
{
other->exportWkbToGeos();
}
Expand Down Expand Up @@ -4161,6 +4185,7 @@ QgsRectangle QgsGeometry::boundingBox()
QgsDebugMsg( "WKB geometry not available!" );
return QgsRectangle( 0, 0, 0, 0 );
}

// consider endian when fetching feature type
//wkbType = (mGeometry[0] == 1) ? mGeometry[1] : mGeometry[4]; //MH: Does not work for 25D geometries
memcpy( &wkbType, &( mGeometry[1] ), sizeof( int ) );
Expand Down Expand Up @@ -6173,10 +6198,14 @@ int QgsGeometry::splitLinearGeometry( GEOSGeometry *splitLine, QList<QgsGeometry
return 2;
}

if ( !mGeos || mDirtyGeos )
if ( mDirtyGeos )
{
if ( !exportWkbToGeos() )
return 5;
exportWkbToGeos();
}

if ( !mGeos )
{
return 5;
}

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

if ( !mGeos || mDirtyGeos )
if ( mDirtyGeos )
{
if ( !exportWkbToGeos() )
return 5;
exportWkbToGeos();
}

if ( !mGeos )
{
return 5;
}

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

int QgsGeometry::mergeGeometriesMultiTypeSplit( QVector<GEOSGeometry*>& splitResult )
{
if ( !mGeos || mDirtyGeos )
if ( mDirtyGeos )
{
if ( !exportWkbToGeos() )
return 1;
exportWkbToGeos();
}

if ( !mGeos )
{
return 1;
}

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

double QgsGeometry::area()
{
if ( !mGeos )
if ( mDirtyGeos )
{
exportWkbToGeos();
}
if ( !mGeos )
{
return -1.0;
}

double area;

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

double QgsGeometry::length()
{
if ( !mGeos )
if ( mDirtyGeos )
{
exportWkbToGeos();
}
if ( !mGeos )
{
return -1.0;
}

double length;

Expand All @@ -7235,12 +7280,11 @@ double QgsGeometry::length()
}
double QgsGeometry::distance( QgsGeometry& geom )
{
if ( !mGeos )
if ( mDirtyGeos )
{
exportWkbToGeos();
}

if ( !geom.mGeos )
if ( geom.mDirtyGeos )
{
geom.exportWkbToGeos();
}
Expand All @@ -7262,7 +7306,7 @@ double QgsGeometry::distance( QgsGeometry& geom )

QgsGeometry* QgsGeometry::buffer( double distance, int segments )
{
if ( !mGeos )
if ( mDirtyGeos )
{
exportWkbToGeos();
}
Expand All @@ -7280,7 +7324,7 @@ QgsGeometry* QgsGeometry::buffer( double distance, int segments )

QgsGeometry* QgsGeometry::simplify( double tolerance )
{
if ( !mGeos )
if ( mDirtyGeos )
{
exportWkbToGeos();
}
Expand All @@ -7297,7 +7341,7 @@ QgsGeometry* QgsGeometry::simplify( double tolerance )

QgsGeometry* QgsGeometry::centroid()
{
if ( !mGeos )
if ( mDirtyGeos )
{
exportWkbToGeos();
}
Expand All @@ -7314,7 +7358,7 @@ QgsGeometry* QgsGeometry::centroid()

QgsGeometry* QgsGeometry::convexHull()
{
if ( !mGeos )
if ( mDirtyGeos )
{
exportWkbToGeos();
}
Expand All @@ -7334,7 +7378,7 @@ QgsGeometry* QgsGeometry::interpolate( double distance )
{
#if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=2)))
if ( !mGeos )
if ( mDirtyGeos )
{
exportWkbToGeos();
}
Expand All @@ -7359,14 +7403,17 @@ QgsGeometry* QgsGeometry::intersection( QgsGeometry* geometry )
{
return NULL;
}
if ( !mGeos )

if ( mDirtyGeos )
{
exportWkbToGeos();
}
if ( !geometry->mGeos )
if ( geometry->mDirtyGeos )
{
geometry->exportWkbToGeos();
}


if ( !mGeos || !geometry->mGeos )
{
return 0;
Expand All @@ -7385,14 +7432,16 @@ QgsGeometry* QgsGeometry::combine( QgsGeometry* geometry )
{
return NULL;
}
if ( !mGeos )

if ( mDirtyGeos )
{
exportWkbToGeos();
}
if ( !geometry->mGeos )
if ( geometry->mDirtyGeos )
{
geometry->exportWkbToGeos();
}

if ( !mGeos || !geometry->mGeos )
{
return 0;
Expand Down Expand Up @@ -7421,14 +7470,16 @@ QgsGeometry* QgsGeometry::difference( QgsGeometry* geometry )
{
return NULL;
}
if ( !mGeos )

if ( mDirtyGeos )
{
exportWkbToGeos();
}
if ( !geometry->mGeos )
if ( geometry->mDirtyGeos )
{
geometry->exportWkbToGeos();
}

if ( !mGeos || !geometry->mGeos )
{
return 0;
Expand All @@ -7447,14 +7498,16 @@ QgsGeometry* QgsGeometry::symDifference( QgsGeometry* geometry )
{
return NULL;
}
if ( !mGeos )

if ( mDirtyGeos )
{
exportWkbToGeos();
}
if ( !geometry->mGeos )
if ( geometry->mDirtyGeos )
{
geometry->exportWkbToGeos();
}

if ( !mGeos || !geometry->mGeos )
{
return 0;
Expand All @@ -7469,11 +7522,14 @@ QgsGeometry* QgsGeometry::symDifference( QgsGeometry* geometry )

QList<QgsGeometry*> QgsGeometry::asGeometryCollection()
{
if ( !mGeos )
if ( mDirtyGeos )
{
exportWkbToGeos();
if ( !mGeos )
return QList<QgsGeometry*>();
}

if ( !mGeos )
{
return QList<QgsGeometry*>();
}

int type = GEOSGeomTypeId( mGeos );
Expand Down

0 comments on commit d8ca919

Please sign in to comment.