Skip to content
Permalink
Browse files

prevent exceeding allocation from corrupt wkb

  • Loading branch information
jef-n committed Feb 18, 2016
1 parent 683cab0 commit d01d42ecba3e8a887f6571ae711616e00694550c
@@ -78,9 +78,9 @@ class CORE_EXPORT QgsWkbPtr
inline void operator+=( int n ) { verifyBound( n ); mP += n; }

inline operator unsigned char *() const { return mP; }
inline int size() const { return mEnd -mStart; }
inline int remaining() const { return mEnd -mP; }
inline int writtenSize() const { return mP -mStart; }
inline int size() const { return mEnd - mStart; }
inline int remaining() const { return mEnd - mP; }
inline int writtenSize() const { return mP - mStart; }
};

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

inline operator const unsigned char *() const { return mP; }
inline int remaining() const { return mEnd -mP; }
inline int remaining() const { return mEnd - mP; }
};

#endif // QGSWKBPTR_H
@@ -19,6 +19,7 @@
#include "qgsclipper.h"
#include "qgsgeometry.h"
#include "qgswkbptr.h"
#include "qgslogger.h"

// Where has all the code gone?

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

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

if ( static_cast<int>( nPoints * ( 2 * sizeof( double ) + skipZM ) ) > wkbPtr.remaining() )
{
QgsDebugMsg( QString( "%1 points exceed wkb length (%2>%3)" ).arg( nPoints ).arg( nPoints * ( 2 * sizeof( double ) + skipZM ) ).arg( wkbPtr.remaining() ) );
return QgsConstWkbPtr( nullptr, 0 );
}

double p0x, p0y, p1x = 0.0, p1y = 0.0; //original coordinates
double p1x_c, p1y_c; //clipped end coordinates
double lastClipX = 0.0, lastClipY = 0.0; //last successfully clipped coords
@@ -82,10 +82,16 @@ QgsConstWkbPtr QgsFeatureRendererV2::_getLineString( QPolygonF& pts, QgsRenderCo
}
else
{
pts.resize( nPoints );

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

This comment has been minimized.

Copy link
@ahuarte47

ahuarte47 Feb 19, 2016

Contributor

Hi @jef-n , there are some identical methods (_getLineString and _getPolygon) in QgsFeatureRendererV2 and QgsSymbolV2 classes.

I created a pull #2802 to remove them.
Could you review it?

Thanks a lot


if ( static_cast<int>( nPoints * ( 2 * sizeof( double ) + skipZM ) ) > wkbPtr.remaining() )
{
QgsDebugMsg( QString( "%1 points exceed wkb length (%2>%3)" ).arg( nPoints ).arg( nPoints * ( 2 * sizeof( double ) + skipZM ) ).arg( wkbPtr.remaining() ) );
return QgsConstWkbPtr( nullptr, 0 );
}

pts.resize( nPoints );

QPointF* ptr = pts.data();
for ( unsigned int i = 0; i < nPoints; ++i, ++ptr )
{
@@ -135,6 +141,12 @@ QgsConstWkbPtr QgsFeatureRendererV2::_getPolygon( QPolygonF& pts, QList<QPolygon
unsigned int nPoints;
wkbPtr >> nPoints;

if ( static_cast<int>( nPoints * ( 2 * sizeof( double ) + skipZM ) ) > wkbPtr.remaining() )
{
QgsDebugMsg( QString( "%1 points exceed wkb length (%2>%3)" ).arg( nPoints ).arg( nPoints * ( 2 * sizeof( double ) + skipZM ) ).arg( wkbPtr.remaining() ) );
return QgsConstWkbPtr( nullptr, 0 );
}

QPolygonF poly( nPoints );

// Extract the points from the WKB and store in a pair of vectors.
@@ -128,11 +128,17 @@ QgsConstWkbPtr QgsSymbolV2::_getLineString( QPolygonF& pts, QgsRenderContext& co
}
else
{
pts.resize( nPoints );

int skipZM = ( QgsWKBTypes::coordDimensions( wkbType ) - 2 ) * sizeof( double );
Q_ASSERT( skipZM >= 0 );

if ( static_cast<int>( nPoints * ( 2 * sizeof( double ) + skipZM ) ) > wkbPtr.remaining() )
{
QgsDebugMsg( QString( "%1 points exceed wkb length (%2>%3)" ).arg( nPoints ).arg( nPoints * ( 2 * sizeof( double ) + skipZM ) ).arg( wkbPtr.remaining() ) );
return QgsConstWkbPtr( nullptr, 0 );
}

pts.resize( nPoints );

QPointF *ptr = pts.data();
for ( unsigned int i = 0; i < nPoints; ++i, ++ptr )
{
@@ -182,6 +188,12 @@ QgsConstWkbPtr QgsSymbolV2::_getPolygon( QPolygonF &pts, QList<QPolygonF> &holes
unsigned int nPoints;
wkbPtr >> nPoints;

if ( static_cast<int>( nPoints * ( 2 * sizeof( double ) + skipZM ) ) > wkbPtr.remaining() )
{
QgsDebugMsg( QString( "%1 points exceed wkb length (%2>%3)" ).arg( nPoints ).arg( nPoints * ( 2 * sizeof( double ) + skipZM ) ).arg( wkbPtr.remaining() ) );
return QgsConstWkbPtr( nullptr, 0 );
}

QPolygonF poly( nPoints );

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

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

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

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

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

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

@@ -849,8 +861,27 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
}
break;
}
case QgsWKBTypes::GeometryCollection:
{
QgsConstWkbPtr wkbPtr( segmentizedGeometry->asWkb(), segmentizedGeometry->wkbSize() );
wkbPtr.readHeader();

int nGeometries;
wkbPtr >> nGeometries;

if ( nGeometries == 0 )
{
// skip noise from empty geometry collections from simplification
break;
}

FALLTHROUGH;
}
default:
QgsDebugMsg( QString( "feature %1: unsupported wkb type 0x%2 for rendering" ).arg( feature.id() ).arg( geom->wkbType(), 0, 16 ) );
QgsDebugMsg( QString( "feature %1: unsupported wkb type %2/%3 for rendering" )
.arg( feature.id() )
.arg( QgsWKBTypes::displayString( geom->geometry()->wkbType() ) )
.arg( geom->wkbType(), 0, 16 ) );
}

if ( drawVertexMarker )

0 comments on commit d01d42e

Please sign in to comment.
You can’t perform that action at this time.