15
15
***************************************************************************/
16
16
17
17
#include < limits>
18
+ #include < stdexcept>
18
19
#include " qgsmaptopixelgeometrysimplifier.h"
19
20
#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
+ };
20
38
21
39
QgsMapToPixelSimplifier::QgsMapToPixelSimplifier ( int simplifyFlags, double tolerance )
22
40
: mSimplifyFlags( simplifyFlags )
@@ -180,6 +198,8 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
180
198
unsigned char * targetPrevWkb = targetWkb;
181
199
int targetWkbPrevSize = targetWkbSize;
182
200
201
+ const unsigned char * endOfSourceWkb = sourceWkb + sourceWkbSize;
202
+
183
203
// Can replace the geometry by its BBOX ?
184
204
if (( simplifyFlags & QgsMapToPixelSimplifier::SimplifyEnvelope ) &&
185
205
isGeneralizableByMapBoundingBox ( envelope, map2pixelTol ) )
@@ -195,6 +215,9 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
195
215
// Write the main header of the geometry
196
216
if ( writeHeader )
197
217
{
218
+ if ( sourceWkbSize < 5 )
219
+ throw QgsParserException ( QString ( " Premature end of WKB reading header " ) );
220
+
198
221
targetWkb[0 ] = sourceWkb[0 ]; // byteOrder
199
222
sourceWkb += 1 ;
200
223
targetWkb += 1 ;
@@ -223,6 +246,9 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
223
246
int sizeOfDoubleX = sizeof ( double );
224
247
int sizeOfDoubleY = ( QGis::wkbDimensions ( wkbType ) - 1 ) * sizeof ( double );
225
248
249
+ if ( sourceWkb + 4 >= endOfSourceWkb )
250
+ throw QgsShortWkbException ( " reading numPoints" );
251
+
226
252
int numPoints;
227
253
memcpy ( &numPoints, sourceWkb, 4 );
228
254
sourceWkb += 4 ;
@@ -250,6 +276,10 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
250
276
const unsigned char * finalWkbX = sourceWkb + ( numPoints - 1 ) * ( sizeOfDoubleX + sizeOfDoubleY );
251
277
const unsigned char * finalWkbY = finalWkbX + sizeOfDoubleX;
252
278
279
+ if ( finalWkbY + sizeof ( double ) > endOfSourceWkb )
280
+ throw QgsShortWkbException ( " reading last point" );
281
+
282
+
253
283
memcpy ( &x1, startWkbX, sizeof ( double ) );
254
284
memcpy ( &y1, startWkbY, sizeof ( double ) );
255
285
memcpy ( &x2, finalWkbX, sizeof ( double ) );
@@ -261,6 +291,11 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
261
291
// Process each vertex...
262
292
for ( int i = 0 ; i < numPoints; ++i )
263
293
{
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
+
264
299
memcpy ( &x, sourceWkb, sizeof ( double ) );
265
300
sourceWkb += sizeOfDoubleX;
266
301
memcpy ( &y, sourceWkb, sizeof ( double ) );
@@ -405,7 +440,7 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
405
440
wkb1 += wkbSize_i;
406
441
}
407
442
}
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 );
409
444
sourceWkb += sourceWkbSize_i;
410
445
targetWkb += targetWkbSize_i;
411
446
@@ -457,13 +492,20 @@ bool QgsMapToPixelSimplifier::simplifyGeometry( QgsGeometry* geometry, int simpl
457
492
unsigned char * targetWkb = new unsigned char [wkbSize];
458
493
memcpy ( targetWkb, wkb, wkbSize );
459
494
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 )
461
507
{
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 () ) );
467
509
}
468
510
delete [] targetWkb;
469
511
return false ;
0 commit comments