Skip to content

Commit d01d42e

Browse files
committedFeb 19, 2016
prevent exceeding allocation from corrupt wkb
1 parent 683cab0 commit d01d42e

File tree

4 files changed

+61
-11
lines changed

4 files changed

+61
-11
lines changed
 

‎src/core/geometry/qgswkbptr.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ class CORE_EXPORT QgsWkbPtr
7878
inline void operator+=( int n ) { verifyBound( n ); mP += n; }
7979

8080
inline operator unsigned char *() const { return mP; }
81-
inline int size() const { return mEnd -mStart; }
82-
inline int remaining() const { return mEnd -mP; }
83-
inline int writtenSize() const { return mP -mStart; }
81+
inline int size() const { return mEnd - mStart; }
82+
inline int remaining() const { return mEnd - mP; }
83+
inline int writtenSize() const { return mP - mStart; }
8484
};
8585

8686
/** \class QgsConstWkbPtr
@@ -118,7 +118,7 @@ class CORE_EXPORT QgsConstWkbPtr
118118
inline void operator-=( int n ) { mP -= n; }
119119

120120
inline operator const unsigned char *() const { return mP; }
121-
inline int remaining() const { return mEnd -mP; }
121+
inline int remaining() const { return mEnd - mP; }
122122
};
123123

124124
#endif // QGSWKBPTR_H

‎src/core/qgsclipper.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "qgsclipper.h"
2020
#include "qgsgeometry.h"
2121
#include "qgswkbptr.h"
22+
#include "qgslogger.h"
2223

2324
// Where has all the code gone?
2425

@@ -46,6 +47,12 @@ QgsConstWkbPtr QgsClipper::clippedLineWKB( QgsConstWkbPtr wkbPtr, const QgsRecta
4647

4748
int skipZM = ( QgsWKBTypes::coordDimensions( wkbType ) - 2 ) * sizeof( double );
4849

50+
if ( static_cast<int>( nPoints * ( 2 * sizeof( double ) + skipZM ) ) > wkbPtr.remaining() )
51+
{
52+
QgsDebugMsg( QString( "%1 points exceed wkb length (%2>%3)" ).arg( nPoints ).arg( nPoints * ( 2 * sizeof( double ) + skipZM ) ).arg( wkbPtr.remaining() ) );
53+
return QgsConstWkbPtr( nullptr, 0 );
54+
}
55+
4956
double p0x, p0y, p1x = 0.0, p1y = 0.0; //original coordinates
5057
double p1x_c, p1y_c; //clipped end coordinates
5158
double lastClipX = 0.0, lastClipY = 0.0; //last successfully clipped coords

‎src/core/symbology-ng/qgsrendererv2.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,16 @@ QgsConstWkbPtr QgsFeatureRendererV2::_getLineString( QPolygonF& pts, QgsRenderCo
8282
}
8383
else
8484
{
85-
pts.resize( nPoints );
86-
8785
int skipZM = ( QgsWKBTypes::coordDimensions( wkbType ) - 2 ) * sizeof( double );
Code has comments. Press enter to view.
8886

87+
if ( static_cast<int>( nPoints * ( 2 * sizeof( double ) + skipZM ) ) > wkbPtr.remaining() )
88+
{
89+
QgsDebugMsg( QString( "%1 points exceed wkb length (%2>%3)" ).arg( nPoints ).arg( nPoints * ( 2 * sizeof( double ) + skipZM ) ).arg( wkbPtr.remaining() ) );
90+
return QgsConstWkbPtr( nullptr, 0 );
91+
}
92+
93+
pts.resize( nPoints );
94+
8995
QPointF* ptr = pts.data();
9096
for ( unsigned int i = 0; i < nPoints; ++i, ++ptr )
9197
{
@@ -135,6 +141,12 @@ QgsConstWkbPtr QgsFeatureRendererV2::_getPolygon( QPolygonF& pts, QList<QPolygon
135141
unsigned int nPoints;
136142
wkbPtr >> nPoints;
137143

144+
if ( static_cast<int>( nPoints * ( 2 * sizeof( double ) + skipZM ) ) > wkbPtr.remaining() )
145+
{
146+
QgsDebugMsg( QString( "%1 points exceed wkb length (%2>%3)" ).arg( nPoints ).arg( nPoints * ( 2 * sizeof( double ) + skipZM ) ).arg( wkbPtr.remaining() ) );
147+
return QgsConstWkbPtr( nullptr, 0 );
148+
}
149+
138150
QPolygonF poly( nPoints );
139151

140152
// Extract the points from the WKB and store in a pair of vectors.

‎src/core/symbology-ng/qgssymbolv2.cpp

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,17 @@ QgsConstWkbPtr QgsSymbolV2::_getLineString( QPolygonF& pts, QgsRenderContext& co
128128
}
129129
else
130130
{
131-
pts.resize( nPoints );
132-
133131
int skipZM = ( QgsWKBTypes::coordDimensions( wkbType ) - 2 ) * sizeof( double );
134132
Q_ASSERT( skipZM >= 0 );
135133

134+
if ( static_cast<int>( nPoints * ( 2 * sizeof( double ) + skipZM ) ) > wkbPtr.remaining() )
135+
{
136+
QgsDebugMsg( QString( "%1 points exceed wkb length (%2>%3)" ).arg( nPoints ).arg( nPoints * ( 2 * sizeof( double ) + skipZM ) ).arg( wkbPtr.remaining() ) );
137+
return QgsConstWkbPtr( nullptr, 0 );
138+
}
139+
140+
pts.resize( nPoints );
141+
136142
QPointF *ptr = pts.data();
137143
for ( unsigned int i = 0; i < nPoints; ++i, ++ptr )
138144
{
@@ -182,6 +188,12 @@ QgsConstWkbPtr QgsSymbolV2::_getPolygon( QPolygonF &pts, QList<QPolygonF> &holes
182188
unsigned int nPoints;
183189
wkbPtr >> nPoints;
184190

191+
if ( static_cast<int>( nPoints * ( 2 * sizeof( double ) + skipZM ) ) > wkbPtr.remaining() )
192+
{
193+
QgsDebugMsg( QString( "%1 points exceed wkb length (%2>%3)" ).arg( nPoints ).arg( nPoints * ( 2 * sizeof( double ) + skipZM ) ).arg( wkbPtr.remaining() ) );
194+
return QgsConstWkbPtr( nullptr, 0 );
195+
}
196+
185197
QPolygonF poly( nPoints );
186198

187199
QPointF *ptr = poly.data();
@@ -801,7 +813,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
801813

802814
const QgsGeometryCollectionV2* geomCollection = dynamic_cast<const QgsGeometryCollectionV2*>( geom->geometry() );
803815

804-
for ( unsigned int i = 0; i < num; ++i )
816+
for ( unsigned int i = 0; i < num && wkbPtr; ++i )
805817
{
806818
mSymbolRenderContext->expressionContextScope()->setVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1 );
807819

@@ -835,7 +847,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
835847

836848
const QgsGeometryCollectionV2* geomCollection = dynamic_cast<const QgsGeometryCollectionV2*>( geom->geometry() );
837849

838-
for ( unsigned int i = 0; i < num; ++i )
850+
for ( unsigned int i = 0; i < num && wkbPtr; ++i )
839851
{
840852
mSymbolRenderContext->expressionContextScope()->setVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1 );
841853

@@ -849,8 +861,27 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
849861
}
850862
break;
851863
}
864+
case QgsWKBTypes::GeometryCollection:
865+
{
866+
QgsConstWkbPtr wkbPtr( segmentizedGeometry->asWkb(), segmentizedGeometry->wkbSize() );
867+
wkbPtr.readHeader();
868+
869+
int nGeometries;
870+
wkbPtr >> nGeometries;
871+
872+
if ( nGeometries == 0 )
873+
{
874+
// skip noise from empty geometry collections from simplification
875+
break;
876+
}
877+
878+
FALLTHROUGH;
879+
}
852880
default:
853-
QgsDebugMsg( QString( "feature %1: unsupported wkb type 0x%2 for rendering" ).arg( feature.id() ).arg( geom->wkbType(), 0, 16 ) );
881+
QgsDebugMsg( QString( "feature %1: unsupported wkb type %2/%3 for rendering" )
882+
.arg( feature.id() )
883+
.arg( QgsWKBTypes::displayString( geom->geometry()->wkbType() ) )
884+
.arg( geom->wkbType(), 0, 16 ) );
854885
}
855886

856887
if ( drawVertexMarker )

0 commit comments

Comments
 (0)
Please sign in to comment.