diff --git a/shapelib.spec b/shapelib.spec index af6e570..2be4bef 100644 --- a/shapelib.spec +++ b/shapelib.spec @@ -3,7 +3,7 @@ Name: shapelib # and since for RPM 1.3.0 < 1.3.0b2, this is the only way to specifiy that 1.3.0 > 1.3.0b2 # without bumping the epoch. Version: 1.3.0f -Release: 2%{?dist} +Release: 3%{?dist} Summary: C library for handling ESRI Shapefiles # The core library is dual-licensed LGPLv2 or MIT. # Some contributed files have different licenses: @@ -21,6 +21,8 @@ Source: http://download.osgeo.org/shapelib/%{name}-1.3.0.tar.gz # # Upstream is notified about these modifications: http://bugzilla.maptools.org/show_bug.cgi?id=2447 Patch0: shapelib_autotools.patch +# Backports from gdal bundled shapelib +Patch1: shapelib_backports.patch BuildRequires: autoconf automake libtool BuildRequires: proj-devel >= 4.4.1 @@ -48,6 +50,7 @@ This package contains various utility programs distributed with shapelib. %prep %setup -q -n %{name}-1.3.0 %patch0 -p1 +%patch1 -p1 %build NOCONFIGURE=1 sh ./autogen.sh @@ -78,6 +81,9 @@ find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' %{_bindir}/* %changelog +* Sun Apr 06 2014 Sandro Mani - 1.3.0f-3 +- Backport some fixes from the gdal bundled shapelib + * Thu Aug 08 2013 Sandro Mani - 1.3.0f-2 - Add missing licenses diff --git a/shapelib_backports.patch b/shapelib_backports.patch new file mode 100644 index 0000000..2f7f123 --- /dev/null +++ b/shapelib_backports.patch @@ -0,0 +1,177 @@ +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..00673aa 100644 +--- a/shptree.c ++++ b/shptree.c +@@ -844,22 +844,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 +869,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 +912,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 +950,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