[shapelib] Backport some fixes from the gdal bundled shapelib
Sandro Mani
smani at fedoraproject.org
Sat Apr 5 21:59:39 UTC 2014
commit 0a82a4ab795cee29f99f994ef1b0bec3c5bbd4c7
Author: Sandro Mani <manisandro at gmail.com>
Date: Sat Apr 5 23:59:28 2014 +0200
Backport some fixes from the gdal bundled shapelib
shapelib.spec | 8 ++-
shapelib_backports.patch | 177 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 184 insertions(+), 1 deletions(-)
---
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 <manisandro at gmail.com> - 1.3.0f-3
+- Backport some fixes from the gdal bundled shapelib
+
* Thu Aug 08 2013 Sandro Mani <manisandro at gmail.com> - 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<numsubnodes; i++)
+ {
+ if( !SHPSearchDiskTreeNode( hDiskTree, padfBoundsMin, padfBoundsMax,
+ ppanResultBuffer, pnBufferMax,
+- pnResultCount, bNeedSwap ) )
++ pnResultCount, bNeedSwap, nRecLevel + 1 ) )
+ return FALSE;
+ }
+
+@@ -1014,7 +1063,7 @@ int* SHPSearchDiskTreeEx( SHPTreeDiskHandle hDiskTree,
+ /* -------------------------------------------------------------------- */
+ if( !SHPSearchDiskTreeNode( hDiskTree, padfBoundsMin, padfBoundsMax,
+ &panResultBuffer, &nBufferMax,
+- pnShapeCount, bNeedSwap ) )
++ pnShapeCount, bNeedSwap, 0 ) )
+ {
+ if( panResultBuffer != NULL )
+ free( panResultBuffer );
+@@ -1025,6 +1074,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;
+ }
More information about the scm-commits
mailing list