Skip to content

Commit bc4d16e

Browse files
author
Sandro Santilli
committedJan 27, 2016
Check WKB boundaries while simplifying for rendering
Fixes crash on simplifying mixed-dimension collections. Closes #12416
1 parent d80a632 commit bc4d16e

File tree

1 file changed

+49
-7
lines changed

1 file changed

+49
-7
lines changed
 

‎src/core/qgsmaptopixelgeometrysimplifier.cpp

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,26 @@
1515
***************************************************************************/
1616

1717
#include <limits>
18+
#include <stdexcept>
1819
#include "qgsmaptopixelgeometrysimplifier.h"
1920
#include "qgsapplication.h"
21+
#include "qgslogger.h"
22+
23+
class QgsParserException: public std::runtime_error
24+
{
25+
public:
26+
QgsParserException( const QString &msg )
27+
: std::runtime_error( msg.toStdString() )
28+
{}
29+
};
30+
31+
class QgsShortWkbException: public QgsParserException
32+
{
33+
public:
34+
QgsShortWkbException( const QString &msg )
35+
: QgsParserException( QString( "Premature end of WKB: " ) + msg )
36+
{}
37+
};
2038

2139
QgsMapToPixelSimplifier::QgsMapToPixelSimplifier( int simplifyFlags, double tolerance )
2240
: mSimplifyFlags( simplifyFlags )
@@ -180,6 +198,8 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
180198
unsigned char* targetPrevWkb = targetWkb;
181199
int targetWkbPrevSize = targetWkbSize;
182200

201+
const unsigned char* endOfSourceWkb = sourceWkb + sourceWkbSize;
202+
183203
// Can replace the geometry by its BBOX ?
184204
if (( simplifyFlags & QgsMapToPixelSimplifier::SimplifyEnvelope ) &&
185205
isGeneralizableByMapBoundingBox( envelope, map2pixelTol ) )
@@ -195,6 +215,9 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
195215
// Write the main header of the geometry
196216
if ( writeHeader )
197217
{
218+
if ( sourceWkbSize < 5 )
219+
throw QgsParserException( QString( "Premature end of WKB reading header " ) );
220+
198221
targetWkb[0] = sourceWkb[0]; // byteOrder
199222
sourceWkb += 1;
200223
targetWkb += 1;
@@ -223,6 +246,9 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
223246
int sizeOfDoubleX = sizeof( double );
224247
int sizeOfDoubleY = ( QGis::wkbDimensions( wkbType ) - 1 ) * sizeof( double );
225248

249+
if ( sourceWkb + 4 >= endOfSourceWkb )
250+
throw QgsShortWkbException( "reading numPoints" );
251+
226252
int numPoints;
227253
memcpy( &numPoints, sourceWkb, 4 );
228254
sourceWkb += 4;
@@ -250,6 +276,10 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
250276
const unsigned char* finalWkbX = sourceWkb + ( numPoints - 1 ) * ( sizeOfDoubleX + sizeOfDoubleY );
251277
const unsigned char* finalWkbY = finalWkbX + sizeOfDoubleX;
252278

279+
if ( finalWkbY + sizeof( double ) > endOfSourceWkb )
280+
throw QgsShortWkbException( "reading last point" );
281+
282+
253283
memcpy( &x1, startWkbX, sizeof( double ) );
254284
memcpy( &y1, startWkbY, sizeof( double ) );
255285
memcpy( &x2, finalWkbX, sizeof( double ) );
@@ -261,6 +291,11 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
261291
// Process each vertex...
262292
for ( int i = 0; i < numPoints; ++i )
263293
{
294+
if ( sourceWkb + sizeOfDoubleX + sizeOfDoubleY > endOfSourceWkb )
295+
{
296+
throw QgsParserException( QString( "Premature end of WKB reading point %1/%2" ) .arg( i + 1 ) .arg( numPoints ) );
297+
}
298+
264299
memcpy( &x, sourceWkb, sizeof( double ) );
265300
sourceWkb += sizeOfDoubleX;
266301
memcpy( &y, sourceWkb, sizeof( double ) );
@@ -405,7 +440,7 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
405440
wkb1 += wkbSize_i;
406441
}
407442
}
408-
result |= simplifyWkbGeometry( simplifyFlags, QGis::singleType( wkbType ), sourceWkb, sourceWkbSize_i, targetWkb, targetWkbSize_i, envelope, map2pixelTol, true, false );
443+
result |= simplifyWkbGeometry( simplifyFlags, QGis::singleType( wkbType ), sourceWkb, endOfSourceWkb - sourceWkb, targetWkb, targetWkbSize_i, envelope, map2pixelTol, true, false );
409444
sourceWkb += sourceWkbSize_i;
410445
targetWkb += targetWkbSize_i;
411446

@@ -457,13 +492,20 @@ bool QgsMapToPixelSimplifier::simplifyGeometry( QgsGeometry* geometry, int simpl
457492
unsigned char* targetWkb = new unsigned char[wkbSize];
458493
memcpy( targetWkb, wkb, wkbSize );
459494

460-
if ( simplifyWkbGeometry( simplifyFlags, wkbType, wkb, wkbSize, targetWkb, finalWkbSize, envelope, tolerance ) )
495+
try
496+
{
497+
if ( simplifyWkbGeometry( simplifyFlags, wkbType, wkb, wkbSize, targetWkb, finalWkbSize, envelope, tolerance ) )
498+
{
499+
unsigned char* finalWkb = new unsigned char[finalWkbSize];
500+
memcpy( finalWkb, targetWkb, finalWkbSize );
501+
geometry->fromWkb( finalWkb, finalWkbSize );
502+
delete [] targetWkb;
503+
return true;
504+
}
505+
}
506+
catch ( const QgsParserException &e )
461507
{
462-
unsigned char* finalWkb = new unsigned char[finalWkbSize];
463-
memcpy( finalWkb, targetWkb, finalWkbSize );
464-
geometry->fromWkb( finalWkb, finalWkbSize );
465-
delete [] targetWkb;
466-
return true;
508+
QgsDebugMsg( QString( "Exception thrown by simplifier: %1" ) .arg( e.what() ) );
467509
}
468510
delete [] targetWkb;
469511
return false;

0 commit comments

Comments
 (0)
Please sign in to comment.