[shapelib/epel7] Backport some fixes from the gdal bundled shapelib

Sandro Mani smani at fedoraproject.org
Sat Apr 5 22:03:32 UTC 2014


commit 70fd35bce4170f46d189e366faba8d76e4713dae
Author: Sandro Mani <manisandro at gmail.com>
Date:   Sun Apr 6 00:03:22 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 a9ff030..3b11671 100644
--- a/shapelib.spec
+++ b/shapelib.spec
@@ -1,6 +1,6 @@
 Name:          shapelib
 Version:       1.3.0
-Release:       1%{?dist}
+Release:       2%{?dist}
 Summary:       C library for handling ESRI Shapefiles
 # The core library is dual-licensed LGPLv2 or MIT.
 # Some contributed files have different licenses:
@@ -18,6 +18,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
@@ -45,6 +47,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
@@ -75,5 +78,8 @@ find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
 %{_bindir}/*
 
 %changelog
+* Sun Apr 06 2014 Sandro Mani <manisandro at gmail.com> - 1.3.0-2
+- Backport some fixes from the gdal bundled shapelib
+
 * Mon Feb 03 2014 Sandro Mani <manisandro at gmail.com> - 1.3.0-1
 - Initial package for epel7
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