Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.2
shapelib
shapelib_backports.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File shapelib_backports.patch of Package shapelib
diff --git a/dbfopen.c b/dbfopen.c index fbe7b06..69d8098 100644 --- a/dbfopen.c +++ b/dbfopen.c @@ -687,15 +687,22 @@ DBFCreateLL( const char * pszFilename, const char * pszCodePage, SAHooks *psHook /* -------------------------------------------------------------------- */ fp = psHooks->FOpen( pszFullname, "wb" ); if( fp == NULL ) + { + free( pszBasename ); + free( pszFullname ); return( NULL ); + } psHooks->FWrite( &chZero, 1, 1, fp ); psHooks->FClose( fp ); fp = psHooks->FOpen( pszFullname, "rb+" ); if( fp == NULL ) + { + free( pszBasename ); + free( pszFullname ); return( NULL ); - + } sprintf( pszFullname, "%s.cpg", pszBasename ); if( pszCodePage != NULL ) diff --git a/shptree.c b/shptree.c index 409134e..4fccfab 100644 --- a/shptree.c +++ b/shptree.c @@ -93,6 +93,7 @@ #include <assert.h> #include <stdlib.h> #include <string.h> +#include <limits.h> #ifdef USE_CPL #include "cpl_error.h" @@ -844,22 +845,23 @@ void SHPCloseDiskTree( SHPTreeDiskHandle hDiskTree ) static int SHPSearchDiskTreeNode( SHPTreeDiskHandle hDiskTree, double *padfBoundsMin, double *padfBoundsMax, int **ppanResultBuffer, int *pnBufferMax, - int *pnResultCount, int bNeedSwap ) + int *pnResultCount, int bNeedSwap, int nRecLevel ) { - int i; - int offset; - int numshapes, numsubnodes; + unsigned int i; + unsigned int offset; + unsigned int numshapes, numsubnodes; double adfNodeBoundsMin[2], adfNodeBoundsMax[2]; + int nFReadAcc; /* -------------------------------------------------------------------- */ /* Read and unswap first part of node info. */ /* -------------------------------------------------------------------- */ - hDiskTree->sHooks.FRead( &offset, 4, 1, hDiskTree->fpQIX ); + nFReadAcc = (int)hDiskTree->sHooks.FRead( &offset, 4, 1, hDiskTree->fpQIX ); if ( bNeedSwap ) SwapWord ( 4, &offset ); - hDiskTree->sHooks.FRead( adfNodeBoundsMin, sizeof(double), 2, hDiskTree->fpQIX ); - hDiskTree->sHooks.FRead( adfNodeBoundsMax, sizeof(double), 2, hDiskTree->fpQIX ); + nFReadAcc += (int)hDiskTree->sHooks.FRead( adfNodeBoundsMin, sizeof(double), 2, hDiskTree->fpQIX ); + nFReadAcc += (int)hDiskTree->sHooks.FRead( adfNodeBoundsMax, sizeof(double), 2, hDiskTree->fpQIX ); if ( bNeedSwap ) { SwapWord( 8, adfNodeBoundsMin + 0 ); @@ -868,9 +870,30 @@ SHPSearchDiskTreeNode( SHPTreeDiskHandle hDiskTree, double *padfBoundsMin, doubl SwapWord( 8, adfNodeBoundsMax + 1 ); } - hDiskTree->sHooks.FRead( &numshapes, 4, 1, hDiskTree->fpQIX ); + nFReadAcc += (int)hDiskTree->sHooks.FRead( &numshapes, 4, 1, hDiskTree->fpQIX ); if ( bNeedSwap ) SwapWord ( 4, &numshapes ); + /* Check that we could read all previous values */ + if( nFReadAcc != 1 + 2 + 2 + 1 ) + { + hDiskTree->sHooks.Error("I/O error"); + return FALSE; + } + + /* Sanity checks to avoid int overflows in later computation */ + if( offset > INT_MAX - sizeof(int) ) + { + hDiskTree->sHooks.Error("Invalid value for offset"); + return FALSE; + } + + if( numshapes > (INT_MAX - offset - sizeof(int)) / sizeof(int) || + numshapes > INT_MAX / sizeof(int) - *pnResultCount ) + { + hDiskTree->sHooks.Error("Invalid value for numshapes"); + return FALSE; + } + /* -------------------------------------------------------------------- */ /* If we don't overlap this node at all, we can just fseek() */ /* pass this node info and all subnodes. */ @@ -890,13 +913,31 @@ SHPSearchDiskTreeNode( SHPTreeDiskHandle hDiskTree, double *padfBoundsMin, doubl { if( *pnResultCount + numshapes > *pnBufferMax ) { - *pnBufferMax = (int) ((*pnResultCount + numshapes + 100) * 1.25); - *ppanResultBuffer = (int *) + int* pNewBuffer; + + *pnBufferMax = (*pnResultCount + numshapes + 100) * 5 / 4; + + if( *pnBufferMax > INT_MAX / sizeof(int) ) + *pnBufferMax = *pnResultCount + numshapes; + + pNewBuffer = (int *) SfRealloc( *ppanResultBuffer, *pnBufferMax * sizeof(int) ); + + if( pNewBuffer == NULL ) + { + hDiskTree->sHooks.Error("Out of memory error"); + return FALSE; + } + + *ppanResultBuffer = pNewBuffer; } - hDiskTree->sHooks.FRead( *ppanResultBuffer + *pnResultCount, - sizeof(int), numshapes, hDiskTree->fpQIX ); + if( hDiskTree->sHooks.FRead( *ppanResultBuffer + *pnResultCount, + sizeof(int), numshapes, hDiskTree->fpQIX ) != numshapes ) + { + hDiskTree->sHooks.Error("I/O error"); + return FALSE; + } if (bNeedSwap ) { @@ -910,14 +951,23 @@ SHPSearchDiskTreeNode( SHPTreeDiskHandle hDiskTree, double *padfBoundsMin, doubl /* -------------------------------------------------------------------- */ /* Process the subnodes. */ /* -------------------------------------------------------------------- */ - hDiskTree->sHooks.FRead( &numsubnodes, 4, 1, hDiskTree->fpQIX ); + if( hDiskTree->sHooks.FRead( &numsubnodes, 4, 1, hDiskTree->fpQIX ) != 1 ) + { + hDiskTree->sHooks.Error("I/O error"); + return FALSE; + } if ( bNeedSwap ) SwapWord ( 4, &numsubnodes ); + if( numsubnodes > 0 && nRecLevel == 32 ) + { + hDiskTree->sHooks.Error("Shape tree is too deep"); + return FALSE; + } for(i=0; i<numsubnodes; i++) { if( !SHPSearchDiskTreeNode( hDiskTree, padfBoundsMin, padfBoundsMax, ppanResultBuffer, pnBufferMax, - pnResultCount, bNeedSwap ) ) + pnResultCount, bNeedSwap, nRecLevel + 1 ) ) return FALSE; } @@ -1014,7 +1064,7 @@ int* SHPSearchDiskTreeEx( SHPTreeDiskHandle hDiskTree, /* -------------------------------------------------------------------- */ if( !SHPSearchDiskTreeNode( hDiskTree, padfBoundsMin, padfBoundsMax, &panResultBuffer, &nBufferMax, - pnShapeCount, bNeedSwap ) ) + pnShapeCount, bNeedSwap, 0 ) ) { if( panResultBuffer != NULL ) free( panResultBuffer ); @@ -1025,6 +1075,10 @@ int* SHPSearchDiskTreeEx( SHPTreeDiskHandle hDiskTree, /* Sort the id array */ /* -------------------------------------------------------------------- */ qsort(panResultBuffer, *pnShapeCount, sizeof(int), compare_ints); + + /* To distinguish between empty intersection from error case */ + if( panResultBuffer == NULL ) + panResultBuffer = (int*) calloc(1, sizeof(int)); return panResultBuffer; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor