[GRASS-SVN] r30804 - grass/trunk/lib/external/shapelib

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Mar 30 05:21:48 EDT 2008


Author: neteler
Date: 2008-03-30 05:21:48 -0400 (Sun, 30 Mar 2008)
New Revision: 30804

Modified:
   grass/trunk/lib/external/shapelib/README
   grass/trunk/lib/external/shapelib/dbfopen.c
   grass/trunk/lib/external/shapelib/shapefil.h
   grass/trunk/lib/external/shapelib/shpopen.c
Log:
sync'ed to GDAL SVN-trunk: gdal/ogr/ogrsf_frmts/shape/

Modified: grass/trunk/lib/external/shapelib/README
===================================================================
--- grass/trunk/lib/external/shapelib/README	2008-03-30 04:01:55 UTC (rev 30803)
+++ grass/trunk/lib/external/shapelib/README	2008-03-30 09:21:48 UTC (rev 30804)
@@ -2,12 +2,12 @@
  ogr/ogrsf_frmts/shape/
 
 Last update
+* taken from GDAL 1.5.1-SVN (Sun Mar 30 11:20:43 CEST 2008)
 * taken from GDAL 1.5.0-CVS (Wed Sep  5 13:48:48 CEST 2007)
-
 * taken from GDAL 1.3.2-CVS (Sat Jun 17 22:08:04 CEST 2006)
 
 Additional fixes:
- - dbfopen.c
+ - dbfopen.c (around line 1013)
    GDAL bug #809 (http://trac.osgeo.org/gdal/ticket/809)
 
  - Use <grass/shapefil.h> etc rather than "shapefil.h"

Modified: grass/trunk/lib/external/shapelib/dbfopen.c
===================================================================
--- grass/trunk/lib/external/shapelib/dbfopen.c	2008-03-30 04:01:55 UTC (rev 30803)
+++ grass/trunk/lib/external/shapelib/dbfopen.c	2008-03-30 09:21:48 UTC (rev 30804)
@@ -33,9 +33,9 @@
  * DEALINGS IN THE SOFTWARE.
  ******************************************************************************
  *
- * $Log$
- * Revision 1.9  2007-09-05 11:50:23  markus
- * SHAPELIB copy updated
+ * $Log: dbfopen.c,v $
+ * Revision 1.74  2007/12/06 07:00:25  fwarmerdam
+ * dbfopen now using SAHooks for fileio
  *
  * Revision 1.73  2007/09/03 19:48:11  fwarmerdam
  * move DBFReadAttribute() static dDoubleField into dbfinfo
@@ -179,9 +179,10 @@
 /*      Write the initial 32 byte file header, and all the field        */
 /*      descriptions.                                     		*/
 /* -------------------------------------------------------------------- */
-    fseek( psDBF->fp, 0, 0 );
-    fwrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp );
-    fwrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, psDBF->fp );
+    psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
+    psDBF->sHooks.FWrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp );
+    psDBF->sHooks.FWrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, 
+                          psDBF->fp );
 
 /* -------------------------------------------------------------------- */
 /*      Write out the newline character if there is room for it.        */
@@ -191,7 +192,7 @@
         char	cNewline;
 
         cNewline = 0x0d;
-        fwrite( &cNewline, 1, 1, psDBF->fp );
+        psDBF->sHooks.FWrite( &cNewline, 1, 1, psDBF->fp );
     }
 }
 
@@ -204,18 +205,20 @@
 static int DBFFlushRecord( DBFHandle psDBF )
 
 {
-    int		nRecordOffset;
+    SAOffset	nRecordOffset;
 
     if( psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1 )
     {
 	psDBF->bCurrentRecordModified = FALSE;
 
-	nRecordOffset = psDBF->nRecordLength * psDBF->nCurrentRecord 
-	                                             + psDBF->nHeaderLength;
+	nRecordOffset = 
+            psDBF->nRecordLength * (SAOffset) psDBF->nCurrentRecord 
+            + psDBF->nHeaderLength;
 
-	if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 
-            || fwrite( psDBF->pszCurrentRecord, psDBF->nRecordLength, 
-                       1, psDBF->fp ) != 1 )
+	if( psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ) != 0 
+            || psDBF->sHooks.FWrite( psDBF->pszCurrentRecord, 
+                                     psDBF->nRecordLength, 
+                                     1, psDBF->fp ) != 1 )
         {
 #ifdef USE_CPL
             CPLError( CE_Failure, CPLE_FileIO, 
@@ -241,28 +244,29 @@
 {
     if( psDBF->nCurrentRecord != iRecord )
     {
-        int nRecordOffset;
+        SAOffset nRecordOffset;
 
 	if( !DBFFlushRecord( psDBF ) )
             return FALSE;
 
-	nRecordOffset = psDBF->nRecordLength * iRecord + psDBF->nHeaderLength;
+	nRecordOffset = 
+            psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
 
-	if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 )
+	if( psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, SEEK_SET ) != 0 )
         {
 #ifdef USE_CPL
             CPLError( CE_Failure, CPLE_FileIO,
-                      "fseek(%d) failed on DBF file.\n",
-                      nRecordOffset );
+                      "fseek(%ld) failed on DBF file.\n",
+                      (long) nRecordOffset );
 #else
-            fprintf( stderr, "fseek(%d) failed on DBF file.\n",
-                     nRecordOffset );
+            fprintf( stderr, "fseek(%ld) failed on DBF file.\n",
+                     (long) nRecordOffset );
 #endif
             return FALSE;
         }
 
-	if( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 
-                   1, psDBF->fp ) != 1 )
+	if( psDBF->sHooks.FRead( psDBF->pszCurrentRecord, 
+                                 psDBF->nRecordLength, 1, psDBF->fp ) != 1 )
         {
 #ifdef USE_CPL
             CPLError( CE_Failure, CPLE_FileIO, 
@@ -296,18 +300,18 @@
 
     DBFFlushRecord( psDBF );
 
-    fseek( psDBF->fp, 0, 0 );
-    fread( abyFileHeader, 32, 1, psDBF->fp );
+    psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
+    psDBF->sHooks.FRead( abyFileHeader, 32, 1, psDBF->fp );
     
     abyFileHeader[4] = (unsigned char) (psDBF->nRecords % 256);
     abyFileHeader[5] = (unsigned char) ((psDBF->nRecords/256) % 256);
     abyFileHeader[6] = (unsigned char) ((psDBF->nRecords/(256*256)) % 256);
     abyFileHeader[7] = (unsigned char) ((psDBF->nRecords/(256*256*256)) % 256);
     
-    fseek( psDBF->fp, 0, 0 );
-    fwrite( abyFileHeader, 32, 1, psDBF->fp );
+    psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
+    psDBF->sHooks.FWrite( abyFileHeader, 32, 1, psDBF->fp );
 
-    fflush( psDBF->fp );
+    psDBF->sHooks.FFlush( psDBF->fp );
 }
 
 /************************************************************************/
@@ -320,8 +324,25 @@
 DBFOpen( const char * pszFilename, const char * pszAccess )
 
 {
+    SAHooks sHooks;
+
+    SASetupDefaultHooks( &sHooks );
+
+    return DBFOpenLL( pszFilename, pszAccess, &sHooks );
+}
+
+/************************************************************************/
+/*                              DBFOpen()                               */
+/*                                                                      */
+/*      Open a .dbf file.                                               */
+/************************************************************************/
+   
+DBFHandle SHPAPI_CALL
+DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks )
+
+{
     DBFHandle		psDBF;
-    unsigned char		*pabyBuf;
+    unsigned char	*pabyBuf;
     int			nFields, nHeadLen, iField, i;
     char		*pszBasename, *pszFullname;
 
@@ -357,12 +378,13 @@
     sprintf( pszFullname, "%s.dbf", pszBasename );
         
     psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );
-    psDBF->fp = fopen( pszFullname, pszAccess );
+    psDBF->fp = psHooks->FOpen( pszFullname, pszAccess );
+    memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) );
 
     if( psDBF->fp == NULL )
     {
         sprintf( pszFullname, "%s.DBF", pszBasename );
-        psDBF->fp = fopen(pszFullname, pszAccess );
+        psDBF->fp = psDBF->sHooks.FOpen(pszFullname, pszAccess );
     }
     
     free( pszBasename );
@@ -382,9 +404,9 @@
 /*  Read Table Header info                                              */
 /* -------------------------------------------------------------------- */
     pabyBuf = (unsigned char *) malloc(500);
-    if( fread( pabyBuf, 32, 1, psDBF->fp ) != 1 )
+    if( psDBF->sHooks.FRead( pabyBuf, 32, 1, psDBF->fp ) != 1 )
     {
-        fclose( psDBF->fp );
+        psDBF->sHooks.FClose( psDBF->fp );
         free( pabyBuf );
         free( psDBF );
         return NULL;
@@ -407,10 +429,10 @@
     pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen);
     psDBF->pszHeader = (char *) pabyBuf;
 
-    fseek( psDBF->fp, 32, 0 );
-    if( fread( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
+    psDBF->sHooks.FSeek( psDBF->fp, 32, 0 );
+    if( psDBF->sHooks.FRead( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
     {
-        fclose( psDBF->fp );
+        psDBF->sHooks.FClose( psDBF->fp );
         free( pabyBuf );
         free( psDBF->pszCurrentRecord );
         free( psDBF );
@@ -484,7 +506,7 @@
 /* -------------------------------------------------------------------- */
 /*      Close, and free resources.                                      */
 /* -------------------------------------------------------------------- */
-    fclose( psDBF->fp );
+    psDBF->sHooks.FClose( psDBF->fp );
 
     if( psDBF->panFieldOffset != NULL )
     {
@@ -513,10 +535,28 @@
 DBFCreate( const char * pszFilename )
 
 {
+    SAHooks sHooks;
+
+    SASetupDefaultHooks( &sHooks );
+
+    return DBFCreateLL( pszFilename, &sHooks );
+}
+
+/************************************************************************/
+/*                             DBFCreate()                              */
+/*                                                                      */
+/*      Create a new .dbf file.                                         */
+/************************************************************************/
+
+DBFHandle SHPAPI_CALL
+DBFCreateLL( const char * pszFilename, SAHooks *psHooks )
+
+{
     DBFHandle	psDBF;
-    FILE	*fp;
+    SAFile	fp;
     char	*pszFullname, *pszBasename;
     int		i;
+    char chZero = '\0';
 
 /* -------------------------------------------------------------------- */
 /*	Compute the base (layer) name.  If there is any extension	*/
@@ -539,14 +579,14 @@
 /* -------------------------------------------------------------------- */
 /*      Create the file.                                                */
 /* -------------------------------------------------------------------- */
-    fp = fopen( pszFullname, "wb" );
+    fp = psHooks->FOpen( pszFullname, "wb" );
     if( fp == NULL )
         return( NULL );
+    
+    psHooks->FWrite( &chZero, 1, 1, fp );
+    psHooks->FClose( fp );
 
-    fputc( 0, fp );
-    fclose( fp );
-
-    fp = fopen( pszFullname, "rb+" );
+    fp = psHooks->FOpen( pszFullname, "rb+" );
     if( fp == NULL )
         return( NULL );
 
@@ -557,6 +597,7 @@
 /* -------------------------------------------------------------------- */
     psDBF = (DBFHandle) calloc(1,sizeof(DBFInfo));
 
+    memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) );
     psDBF->fp = fp;
     psDBF->nRecords = 0;
     psDBF->nFields = 0;

Modified: grass/trunk/lib/external/shapelib/shapefil.h
===================================================================
--- grass/trunk/lib/external/shapelib/shapefil.h	2008-03-30 04:01:55 UTC (rev 30803)
+++ grass/trunk/lib/external/shapelib/shapefil.h	2008-03-30 09:21:48 UTC (rev 30804)
@@ -36,10 +36,23 @@
  * DEALINGS IN THE SOFTWARE.
  ******************************************************************************
  *
- * $Log$
- * Revision 1.6  2007-09-05 11:50:23  markus
- * SHAPELIB copy updated
+ * $Log: shapefil.h,v $
+ * Revision 1.40  2007/12/06 07:00:25  fwarmerdam
+ * dbfopen now using SAHooks for fileio
  *
+ * Revision 1.39  2007/12/04 20:37:56  fwarmerdam
+ * preliminary implementation of hooks api for io and errors
+ *
+ * Revision 1.38  2007/11/21 22:39:56  fwarmerdam
+ * close shx file in readonly mode (GDAL #1956)
+ *
+ * Revision 1.37  2007/10/27 03:31:14  fwarmerdam
+ * limit default depth of tree to 12 levels (gdal ticket #1594)
+ *
+ * Revision 1.36  2007/09/10 23:33:15  fwarmerdam
+ * Upstreamed support for visibility flag in SHPAPI_CALL for the needs
+ * of GDAL (gdal ticket #1810).
+ *
  * Revision 1.35  2007/09/03 19:48:10  fwarmerdam
  * move DBFReadAttribute() static dDoubleField into dbfinfo
  *
@@ -91,6 +104,7 @@
 
 #ifdef USE_CPL
 #include "cpl_error.h"
+#include "cpl_vsi.h"
 #endif
 
 #ifdef __cplusplus
@@ -113,7 +127,7 @@
 /*      is disabled.                                                    */
 /* -------------------------------------------------------------------- */
 #define DISABLE_MULTIPATCH_MEASURE
-
+    
 /* -------------------------------------------------------------------- */
 /*      SHPAPI_CALL                                                     */
 /*                                                                      */
@@ -149,7 +163,12 @@
 #endif
 
 #ifndef SHPAPI_CALL
-#  define SHPAPI_CALL
+#  if defined(USE_GCC_VISIBILITY_FLAG)
+#    define SHPAPI_CALL     __attribute__ ((visibility("default")))
+#    define SHPAPI_CALL1(x) __attribute__ ((visibility("default")))     x
+#  else
+#    define SHPAPI_CALL
+#  endif
 #endif
 
 #ifndef SHPAPI_CALL1
@@ -166,15 +185,40 @@
 #else
 #  define SHP_CVSID(string)
 #endif
+    
+/* -------------------------------------------------------------------- */
+/*      IO/Error hook functions.                                        */
+/* -------------------------------------------------------------------- */
+typedef int *SAFile;
 
+#ifndef SAOffset
+typedef unsigned long SAOffset;
+#endif
+
+typedef struct {
+    SAFile     (*FOpen) ( const char *filename, const char *path);
+    SAOffset   (*FRead) ( void *p, SAOffset size, SAOffset nmemb, SAFile file);
+    SAOffset   (*FWrite)( void *p, SAOffset size, SAOffset nmemb, SAFile file);
+    SAOffset   (*FSeek) ( SAFile file, SAOffset offset, int whence );
+    SAOffset   (*FTell) ( SAFile file );
+    int        (*FFlush)( SAFile file );
+    int        (*FClose)( SAFile file );
+
+    void       (*Error) ( const char *message );
+} SAHooks;
+
+void SHPAPI_CALL SASetupDefaultHooks( SAHooks *psHooks );
+
 /************************************************************************/
 /*                             SHP Support.                             */
 /************************************************************************/
 typedef	struct
 {
-    FILE        *fpSHP;
-    FILE	*fpSHX;
+    SAHooks sHooks;
 
+    SAFile      fpSHP;
+    SAFile 	fpSHX;
+
     int		nShapeType;				/* SHPT_* */
     
     int		nFileSize;				/* SHP file */
@@ -262,10 +306,19 @@
 /* -------------------------------------------------------------------- */
 /*      SHP API Prototypes                                              */
 /* -------------------------------------------------------------------- */
+
+/* If pszAccess is read-only, the fpSHX field of the returned structure */
+/* will be NULL as it is not necessary to keep the SHX file open */
 SHPHandle SHPAPI_CALL
       SHPOpen( const char * pszShapeFile, const char * pszAccess );
 SHPHandle SHPAPI_CALL
+      SHPOpenLL( const char *pszShapeFile, const char *pszAccess, 
+                 SAHooks *psHooks );
+SHPHandle SHPAPI_CALL
       SHPCreate( const char * pszShapeFile, int nShapeType );
+SHPHandle SHPAPI_CALL
+      SHPCreateLL( const char * pszShapeFile, int nShapeType,
+                   SAHooks *psHooks );
 void SHPAPI_CALL
       SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
                   double * padfMinBound, double * padfMaxBound );
@@ -309,6 +362,9 @@
 /* this can be two or four for binary or quad tree */
 #define MAX_SUBNODE	4
 
+/* upper limit of tree levels for automatic estimation */
+#define MAX_DEFAULT_TREE_DEPTH 12
+
 typedef struct shape_tree_node
 {
     /* region covered by this node */
@@ -376,8 +432,10 @@
 /************************************************************************/
 typedef	struct
 {
-    FILE	*fp;
+    SAHooks sHooks;
 
+    SAFile	fp;
+
     int         nRecords;
 
     int		nRecordLength;
@@ -415,10 +473,16 @@
 
 #define XBASE_FLDHDR_SZ       32
 
+
 DBFHandle SHPAPI_CALL
       DBFOpen( const char * pszDBFFile, const char * pszAccess );
 DBFHandle SHPAPI_CALL
+      DBFOpenLL( const char * pszDBFFile, const char * pszAccess,
+                 SAHooks *psHooks );
+DBFHandle SHPAPI_CALL
       DBFCreate( const char * pszDBFFile );
+DBFHandle SHPAPI_CALL
+      DBFCreateLL( const char * pszDBFFile, SAHooks *psHooks );
 
 int	SHPAPI_CALL
       DBFGetFieldCount( DBFHandle psDBF );

Modified: grass/trunk/lib/external/shapelib/shpopen.c
===================================================================
--- grass/trunk/lib/external/shapelib/shpopen.c	2008-03-30 04:01:55 UTC (rev 30803)
+++ grass/trunk/lib/external/shapelib/shpopen.c	2008-03-30 09:21:48 UTC (rev 30804)
@@ -33,10 +33,32 @@
  * DEALINGS IN THE SOFTWARE.
  ******************************************************************************
  *
- * $Log$
- * Revision 1.7  2007-09-05 11:50:23  markus
- * SHAPELIB copy updated
+ * $Log: shpopen.c,v $
+ * Revision 1.59  2008/03/14 05:25:31  fwarmerdam
+ * Correct crash on buggy geometries (gdal #2218)
  *
+ * Revision 1.58  2008/01/08 23:28:26  bram
+ * on line 2095, use a float instead of a double to avoid a compiler warning
+ *
+ * Revision 1.57  2007/12/06 07:00:25  fwarmerdam
+ * dbfopen now using SAHooks for fileio
+ *
+ * Revision 1.56  2007/12/04 20:37:56  fwarmerdam
+ * preliminary implementation of hooks api for io and errors
+ *
+ * Revision 1.55  2007/11/21 22:39:56  fwarmerdam
+ * close shx file in readonly mode (GDAL #1956)
+ *
+ * Revision 1.54  2007/11/15 00:12:47  mloskot
+ * Backported recent changes from GDAL (Ticket #1415) to Shapelib.
+ *
+ * Revision 1.53  2007/11/14 22:31:08  fwarmerdam
+ * checks after mallocs to detect for corrupted/voluntary broken shapefiles.
+ * http://trac.osgeo.org/gdal/ticket/1991
+ *
+ * Revision 1.52  2007/06/21 15:58:33  fwarmerdam
+ * fix for SHPRewindObject when rings touch at one vertex (gdal #976)
+ *
  * Revision 1.51  2006/09/04 15:24:01  fwarmerdam
  * Fixed up log message for 1.49.
  *
@@ -208,9 +230,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
-#ifdef USE_CPL
-#include <cpl_vsi.h>
-#endif
 
 SHP_CVSID("$Id$")
 
@@ -287,6 +306,12 @@
     int32	i32;
     double	dValue;
     int32	*panSHX;
+    
+    if (psSHP->fpSHX == NULL)
+    {
+        psSHP->sHooks.Error( "SHPWriteHeader failed : SHX file is closed");
+        return;
+    }
 
 /* -------------------------------------------------------------------- */
 /*      Prepare header block for .shp file.                             */
@@ -344,13 +369,10 @@
 /* -------------------------------------------------------------------- */
 /*      Write .shp file header.                                         */
 /* -------------------------------------------------------------------- */
-    if( fseek( psSHP->fpSHP, 0, 0 ) != 0 
-        || fwrite( abyHeader, 100, 1, psSHP->fpSHP ) != 1 )
+    if( psSHP->sHooks.FSeek( psSHP->fpSHP, 0, 0 ) != 0 
+        || psSHP->sHooks.FWrite( abyHeader, 100, 1, psSHP->fpSHP ) != 1 )
     {
-#ifdef USE_CPL
-        CPLError( CE_Failure, CPLE_OpenFailed, 
-                  "Failure writing .shp header (%s)", VSIStrerror( errno ) );
-#endif
+        psSHP->sHooks.Error( "Failure writing .shp header" );
         return;
     }
 
@@ -361,13 +383,10 @@
     ByteCopy( &i32, abyHeader+24, 4 );
     if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
     
-    if( fseek( psSHP->fpSHX, 0, 0 ) != 0 
-        || fwrite( abyHeader, 100, 1, psSHP->fpSHX ) != 1 )
+    if( psSHP->sHooks.FSeek( psSHP->fpSHX, 0, 0 ) != 0 
+        || psSHP->sHooks.FWrite( abyHeader, 100, 1, psSHP->fpSHX ) != 1 )
     {
-#ifdef USE_CPL
-        CPLError( CE_Failure, CPLE_OpenFailed, 
-                  "Failure writing .shx header (%s)", VSIStrerror( errno ) );
-#endif
+        psSHP->sHooks.Error( "Failure writing .shx header" );
         return;
     }
 
@@ -384,13 +403,10 @@
 	if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 );
     }
 
-    if( (int)fwrite( panSHX, sizeof(int32)*2, psSHP->nRecords, psSHP->fpSHX ) 
+    if( (int)psSHP->sHooks.FWrite( panSHX, sizeof(int32)*2, psSHP->nRecords, psSHP->fpSHX ) 
         != psSHP->nRecords )
     {
-#ifdef USE_CPL
-        CPLError( CE_Failure, CPLE_OpenFailed, 
-                  "Failure writing .shx contents (%s)", VSIStrerror( errno ) );
-#endif
+        psSHP->sHooks.Error( "Failure writing .shx contents" );
     }
 
     free( panSHX );
@@ -398,19 +414,34 @@
 /* -------------------------------------------------------------------- */
 /*      Flush to disk.                                                  */
 /* -------------------------------------------------------------------- */
-    fflush( psSHP->fpSHP );
-    fflush( psSHP->fpSHX );
+    psSHP->sHooks.FFlush( psSHP->fpSHP );
+    psSHP->sHooks.FFlush( psSHP->fpSHX );
 }
 
 /************************************************************************/
-/*                              shpopen()                               */
+/*                              SHPOpen()                               */
+/************************************************************************/
+
+SHPHandle SHPAPI_CALL
+SHPOpen( const char * pszLayer, const char * pszAccess )
+
+{
+    SAHooks sHooks;
+
+    SASetupDefaultHooks( &sHooks );
+
+    return SHPOpenLL( pszLayer, pszAccess, &sHooks );
+}
+
+/************************************************************************/
+/*                              SHPOpen()                               */
 /*                                                                      */
 /*      Open the .shp and .shx files based on the basename of the       */
 /*      files or either file name.                                      */
 /************************************************************************/
    
 SHPHandle SHPAPI_CALL
-SHPOpen( const char * pszLayer, const char * pszAccess )
+SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks )
 
 {
     char		*pszFullname, *pszBasename;
@@ -446,6 +477,7 @@
     psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1);
 
     psSHP->bUpdated = FALSE;
+    memcpy( &(psSHP->sHooks), psHooks, sizeof(SAHooks) );
 
 /* -------------------------------------------------------------------- */
 /*	Compute the base (layer) name.  If there is any extension	*/
@@ -466,12 +498,12 @@
 /*	a PC to Unix with upper case filenames won't work!		*/
 /* -------------------------------------------------------------------- */
     pszFullname = (char *) malloc(strlen(pszBasename) + 5);
-    sprintf( pszFullname, "%s.shp", pszBasename );
-    psSHP->fpSHP = fopen(pszFullname, pszAccess );
+    sprintf( pszFullname, "%s.shp", pszBasename ) ;
+    psSHP->fpSHP = psSHP->sHooks.FOpen(pszFullname, pszAccess );
     if( psSHP->fpSHP == NULL )
     {
         sprintf( pszFullname, "%s.SHP", pszBasename );
-        psSHP->fpSHP = fopen(pszFullname, pszAccess );
+        psSHP->fpSHP = psSHP->sHooks.FOpen(pszFullname, pszAccess );
     }
     
     if( psSHP->fpSHP == NULL )
@@ -488,11 +520,11 @@
     }
 
     sprintf( pszFullname, "%s.shx", pszBasename );
-    psSHP->fpSHX = fopen(pszFullname, pszAccess );
+    psSHP->fpSHX =  psSHP->sHooks.FOpen(pszFullname, pszAccess );
     if( psSHP->fpSHX == NULL )
     {
         sprintf( pszFullname, "%s.SHX", pszBasename );
-        psSHP->fpSHX = fopen(pszFullname, pszAccess );
+        psSHP->fpSHX = psSHP->sHooks.FOpen(pszFullname, pszAccess );
     }
     
     if( psSHP->fpSHX == NULL )
@@ -502,7 +534,7 @@
                   "Unable to open %s.shx or %s.SHX.", 
                   pszBasename, pszBasename );
 #endif
-        fclose( psSHP->fpSHP );
+        psSHP->sHooks.FClose( psSHP->fpSHP );
         free( psSHP );
         free( pszBasename );
         free( pszFullname );
@@ -516,7 +548,7 @@
 /*  Read the file size from the SHP file.				*/
 /* -------------------------------------------------------------------- */
     pabyBuf = (uchar *) malloc(100);
-    fread( pabyBuf, 100, 1, psSHP->fpSHP );
+    psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHP );
 
     psSHP->nFileSize = (pabyBuf[24] * 256 * 256 * 256
 			+ pabyBuf[25] * 256 * 256
@@ -526,18 +558,15 @@
 /* -------------------------------------------------------------------- */
 /*  Read SHX file Header info                                           */
 /* -------------------------------------------------------------------- */
-    if( fread( pabyBuf, 100, 1, psSHP->fpSHX ) != 1 
+    if( psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHX ) != 1 
         || pabyBuf[0] != 0 
         || pabyBuf[1] != 0 
         || pabyBuf[2] != 0x27 
         || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) )
     {
-#ifdef USE_CPL
-        CPLError( CE_Failure, CPLE_AppDefined, 
-                  ".shx file is unreadable, or corrupt." );
-#endif
-	fclose( psSHP->fpSHP );
-	fclose( psSHP->fpSHX );
+        psSHP->sHooks.Error( ".shx file is unreadable, or corrupt." );
+	psSHP->sHooks.FClose( psSHP->fpSHP );
+	psSHP->sHooks.FClose( psSHP->fpSHX );
 	free( psSHP );
 
 	return( NULL );
@@ -551,15 +580,17 @@
 
     if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 )
     {
-#ifdef USE_CPL
-        CPLError( CE_Failure, CPLE_AppDefined, 
-                  "Record count in .shp header is %d, which seems\n"
-                  "unreasonable.  Assuming header is corrupt.",
+        char szError[200];
+        
+        sprintf( szError, 
+                 "Record count in .shp header is %d, which seems\n"
+                 "unreasonable.  Assuming header is corrupt.",
                   psSHP->nRecords );
-#endif
-	fclose( psSHP->fpSHP );
-	fclose( psSHP->fpSHX );
+        psSHP->sHooks.Error( szError );				       
+	psSHP->sHooks.FClose( psSHP->fpSHP );
+	psSHP->sHooks.FClose( psSHP->fpSHX );
 	free( psSHP );
+        free(pabyBuf);
 
 	return( NULL );
     }
@@ -611,25 +642,55 @@
         (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );
     psSHP->panRecSize =
         (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );
+    pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) );
 
-    pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) );
-    if( (int) fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX ) 
+    if (psSHP->panRecOffset == NULL ||
+        psSHP->panRecSize == NULL ||
+        pabyBuf == NULL)
+    {
+        char szError[200];
+
+        sprintf(szError, 
+                "Not enough memory to allocate requested memory (nRecords=%d).\n"
+                "Probably broken SHP file", 
+                psSHP->nRecords );
+        psSHP->sHooks.Error( szError );
+	psSHP->sHooks.FClose( psSHP->fpSHP );
+	psSHP->sHooks.FClose( psSHP->fpSHX );
+        if (psSHP->panRecOffset) free( psSHP->panRecOffset );
+        if (psSHP->panRecSize) free( psSHP->panRecSize );
+        if (pabyBuf) free( pabyBuf );
+        free( psSHP );
+        return( NULL );
+    }
+
+    if( (int) psSHP->sHooks.FRead( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX ) 
 			!= psSHP->nRecords )
     {
-#ifdef USE_CPL
-        CPLError( CE_Failure, CPLE_AppDefined, 
-                  "Failed to read all values for %d records in .shx file.",
-                  psSHP->nRecords );
-#endif
+        char szError[200];
+
+        sprintf( szError, 
+                 "Failed to read all values for %d records in .shx file.",
+                 psSHP->nRecords );
+        psSHP->sHooks.Error( szError );
+
         /* SHX is short or unreadable for some reason. */
-	fclose( psSHP->fpSHP );
-	fclose( psSHP->fpSHX );
+	psSHP->sHooks.FClose( psSHP->fpSHP );
+	psSHP->sHooks.FClose( psSHP->fpSHX );
         free( psSHP->panRecOffset );
         free( psSHP->panRecSize );
+        free( pabyBuf );
 	free( psSHP );
 
 	return( NULL );
     }
+    
+    /* In read-only mode, we can close the SHX now */
+    if (strcmp(pszAccess, "rb") == 0)
+    {
+        psSHP->sHooks.FClose( psSHP->fpSHX );
+        psSHP->fpSHX = NULL;
+    }
 
     for( i = 0; i < psSHP->nRecords; i++ )
     {
@@ -674,8 +735,9 @@
     free( psSHP->panRecOffset );
     free( psSHP->panRecSize );
 
-    fclose( psSHP->fpSHX );
-    fclose( psSHP->fpSHP );
+    if ( psSHP->fpSHX != NULL)
+        psSHP->sHooks.FClose( psSHP->fpSHX );
+    psSHP->sHooks.FClose( psSHP->fpSHP );
 
     if( psSHP->pabyRec != NULL )
     {
@@ -727,9 +789,27 @@
 SHPCreate( const char * pszLayer, int nShapeType )
 
 {
+    SAHooks sHooks;
+
+    SASetupDefaultHooks( &sHooks );
+
+    return SHPCreateLL( pszLayer, nShapeType, &sHooks );
+}
+
+/************************************************************************/
+/*                             SHPCreate()                              */
+/*                                                                      */
+/*      Create a new shape file and return a handle to the open         */
+/*      shape file with read/write access.                              */
+/************************************************************************/
+
+SHPHandle SHPAPI_CALL
+SHPCreateLL( const char * pszLayer, int nShapeType, SAHooks *psHooks )
+
+{
     char	*pszBasename, *pszFullname;
     int		i;
-    FILE	*fpSHP, *fpSHX;
+    SAFile	fpSHP, fpSHX;
     uchar     	abyHeader[100];
     int32	i32;
     double	dValue;
@@ -762,26 +842,18 @@
 /* -------------------------------------------------------------------- */
     pszFullname = (char *) malloc(strlen(pszBasename) + 5);
     sprintf( pszFullname, "%s.shp", pszBasename );
-    fpSHP = fopen(pszFullname, "wb" );
+    fpSHP = psHooks->FOpen(pszFullname, "wb" );
     if( fpSHP == NULL )
     {
-#ifdef USE_CPL
-        CPLError( CE_Failure, CPLE_AppDefined, 
-                  "Failed to create file %s.",
-                  pszFullname );
-#endif
+        psHooks->Error( "Failed to create file .shp file." );
         return( NULL );
     }
 
     sprintf( pszFullname, "%s.shx", pszBasename );
-    fpSHX = fopen(pszFullname, "wb" );
+    fpSHX = psHooks->FOpen(pszFullname, "wb" );
     if( fpSHX == NULL )
     {
-#ifdef USE_CPL
-        CPLError( CE_Failure, CPLE_AppDefined, 
-                  "Failed to create file %s.",
-                  pszFullname );
-#endif
+        psHooks->Error( "Failed to create file .shx file." );
         return( NULL );
     }
 
@@ -818,12 +890,9 @@
 /* -------------------------------------------------------------------- */
 /*      Write .shp file header.                                         */
 /* -------------------------------------------------------------------- */
-    if( fwrite( abyHeader, 100, 1, fpSHP ) != 1 )
+    if( psHooks->FWrite( abyHeader, 100, 1, fpSHP ) != 1 )
     {
-#ifdef USE_CPL
-        CPLError( CE_Failure, CPLE_AppDefined, 
-                  "Failed to write .shp header." );
-#endif
+        psHooks->Error( "Failed to write .shp header." );
         return NULL;
     }
 
@@ -834,22 +903,19 @@
     ByteCopy( &i32, abyHeader+24, 4 );
     if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
     
-    if( fwrite( abyHeader, 100, 1, fpSHX ) != 1 )
+    if( psHooks->FWrite( abyHeader, 100, 1, fpSHX ) != 1 )
     {
-#ifdef USE_CPL
-        CPLError( CE_Failure, CPLE_AppDefined, 
-                  "Failed to write .shx header." );
-#endif
+        psHooks->Error( "Failed to write .shx header." );
         return NULL;
     }
 
 /* -------------------------------------------------------------------- */
 /*      Close the files, and then open them as regular existing files.  */
 /* -------------------------------------------------------------------- */
-    fclose( fpSHP );
-    fclose( fpSHX );
+    psHooks->FClose( fpSHP );
+    psHooks->FClose( fpSHX );
 
-    return( SHPOpen( pszLayer, "r+b" ) );
+    return( SHPOpenLL( pszLayer, "r+b", psHooks ) );
 }
 
 /************************************************************************/
@@ -992,15 +1058,7 @@
         }
 
         if( psObject->panPartStart[0] != 0 )
-        {
-#ifdef USE_CPL
-            CPLError( CE_Failure, CPLE_AppDefined,
-                      "panPartStart[0] != 0, patching internally.  Please fix your code!\n" );
-#else
-            fprintf( stderr, "panPartStart[0] != 0, patching internally.  Please fix your code!\n" );
-#endif
             psObject->panPartStart[0] = 0;
-        }
     }
 
 /* -------------------------------------------------------------------- */
@@ -1382,13 +1440,10 @@
 /* -------------------------------------------------------------------- */
 /*      Write out record.                                               */
 /* -------------------------------------------------------------------- */
-    if( fseek( psSHP->fpSHP, nRecordOffset, 0 ) != 0
-        || fwrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 )
+    if( psSHP->sHooks.FSeek( psSHP->fpSHP, nRecordOffset, 0 ) != 0
+        || psSHP->sHooks.FWrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 )
     {
-#ifdef USE_CPL
-        CPLError( CE_Failure, CPLE_FileIO, 
-                "Error in fseek() or fwrite() writing object to .shp file." );
-#endif
+        psSHP->sHooks.Error( "Error in psSHP->sHooks.FSeek() or fwrite() writing object to .shp file." );
         free( pabyRec );
         return -1;
     }
@@ -1445,7 +1500,9 @@
 SHPReadObject( SHPHandle psSHP, int hEntity )
 
 {
+    int                  nEntitySize, nRequiredSize;
     SHPObject		*psShape;
+    char                 pszErrorMsg[128];
 
 /* -------------------------------------------------------------------- */
 /*      Validate the record/entity number.                              */
@@ -1456,17 +1513,39 @@
 /* -------------------------------------------------------------------- */
 /*      Ensure our record buffer is large enough.                       */
 /* -------------------------------------------------------------------- */
-    if( psSHP->panRecSize[hEntity]+8 > psSHP->nBufSize )
+    nEntitySize = psSHP->panRecSize[hEntity]+8;
+    if( nEntitySize > psSHP->nBufSize )
     {
-	psSHP->nBufSize = psSHP->panRecSize[hEntity]+8;
-	psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,psSHP->nBufSize);
+	psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,nEntitySize);
+        if (psSHP->pabyRec == NULL)
+        {
+            char szError[200];
+
+            /* Reallocate previous successfull size for following features */
+            psSHP->pabyRec = malloc(psSHP->nBufSize);
+
+            sprintf( szError, 
+                     "Not enough memory to allocate requested memory (nBufSize=%d). "
+                     "Probably broken SHP file", psSHP->nBufSize );
+            psSHP->sHooks.Error( szError );
+            return NULL;
+        }
+
+        /* Only set new buffer size after successfull alloc */
+	psSHP->nBufSize = nEntitySize;
     }
 
+    /* In case we were not able to reallocate the buffer on a previous step */
+    if (psSHP->pabyRec == NULL)
+    {
+        return NULL;
+    }
+
 /* -------------------------------------------------------------------- */
 /*      Read the record.                                                */
 /* -------------------------------------------------------------------- */
-    if( fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0 
-        || fread( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1, 
+    if( psSHP->sHooks.FSeek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0 
+        || psSHP->sHooks.FRead( psSHP->pabyRec, nEntitySize, 1, 
                   psSHP->fpSHP ) != 1 )
     {
         /*
@@ -1474,9 +1553,7 @@
          * for example to detect if file is truncated.
          */
 
-#ifdef USE_CPL
-        CPLDebug( "Shape", "Error in fseek() or fread() reading object from .shp file." );
-#endif
+        psSHP->sHooks.Error( "Error in fseek() or fread() reading object from .shp file." );
         return NULL;
     }
 
@@ -1487,7 +1564,16 @@
     psShape->nShapeId = hEntity;
     psShape->bMeasureIsUsed = FALSE;
 
+    if ( 8 + 4 > nEntitySize )
+    {
+        snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nEntitySize = %d",
+                    hEntity, nEntitySize); 
+        psSHP->sHooks.Error( pszErrorMsg );
+        SHPDestroyObject(psShape);
+        return NULL;
+    }
     memcpy( &psShape->nSHPType, psSHP->pabyRec + 8, 4 );
+
     if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) );
 
 /* ==================================================================== */
@@ -1503,6 +1589,14 @@
 	int32		nPoints, nParts;
 	int    		i, nOffset;
 
+        if ( 40 + 8 + 4 > nEntitySize )
+        {
+            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nEntitySize = %d",
+                     hEntity, nEntitySize); 
+            psSHP->sHooks.Error( pszErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
 /* -------------------------------------------------------------------- */
 /*	Get the X/Y bounds.						*/
 /* -------------------------------------------------------------------- */
@@ -1526,6 +1620,39 @@
 	if( bBigEndian ) SwapWord( 4, &nPoints );
 	if( bBigEndian ) SwapWord( 4, &nParts );
 
+        if (nPoints < 0 || nParts < 0 ||
+            nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000)
+        {
+            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d, nPoints=%d, nParts=%d.",
+                        hEntity, nPoints, nParts);
+            psSHP->sHooks.Error( pszErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
+        
+        /* With the previous checks on nPoints and nParts, */
+        /* we should not overflow here and after */
+        /* since 50 M * (16 + 8 + 8) = 1 600 MB */
+        nRequiredSize = 44 + 8 + 4 * nParts + 16 * nPoints;
+        if ( psShape->nSHPType == SHPT_POLYGONZ
+            || psShape->nSHPType == SHPT_ARCZ
+            || psShape->nSHPType == SHPT_MULTIPATCH )
+        {
+            nRequiredSize += 16 + 8 * nPoints;
+        }
+        if( psShape->nSHPType == SHPT_MULTIPATCH )
+        {
+            nRequiredSize += 4 * nParts;
+        }
+        if (nRequiredSize > nEntitySize)
+        {
+            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d, nPoints=%d, nParts=%d, nEntitySize=%d.",
+                        hEntity, nPoints, nParts, nEntitySize);
+            psSHP->sHooks.Error( pszErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
+
 	psShape->nVertices = nPoints;
         psShape->padfX = (double *) calloc(nPoints,sizeof(double));
         psShape->padfY = (double *) calloc(nPoints,sizeof(double));
@@ -1535,6 +1662,21 @@
 	psShape->nParts = nParts;
         psShape->panPartStart = (int *) calloc(nParts,sizeof(int));
         psShape->panPartType = (int *) calloc(nParts,sizeof(int));
+        
+        if (psShape->padfX == NULL ||
+            psShape->padfY == NULL ||
+            psShape->padfZ == NULL ||
+            psShape->padfM == NULL ||
+            psShape->panPartStart == NULL ||
+            psShape->panPartType == NULL)
+        {
+            snprintf(pszErrorMsg, 128,
+                     "Not enough memory to allocate requested memory (nPoints=%d, nParts=%d) for shape %d. "
+                     "Probably broken SHP file", hEntity, nPoints, nParts );
+            psSHP->sHooks.Error( pszErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
 
         for( i = 0; i < nParts; i++ )
             psShape->panPartType[i] = SHPP_RING;
@@ -1546,6 +1688,25 @@
 	for( i = 0; i < nParts; i++ )
 	{
 	    if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i );
+
+            /* We check that the offset is inside the vertex array */
+            if (psShape->panPartStart[i] < 0 ||
+                psShape->panPartStart[i] >= psShape->nVertices)
+            {
+                snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : panPartStart[%d] = %d, nVertices = %d",
+                         hEntity, i, psShape->panPartStart[i], psShape->nVertices); 
+                psSHP->sHooks.Error( pszErrorMsg );
+                SHPDestroyObject(psShape);
+                return NULL;
+            }
+            if (i > 0 && psShape->panPartStart[i] <= psShape->panPartStart[i-1])
+            {
+                snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : panPartStart[%d] = %d, panPartStart[%d] = %d",
+                         hEntity, i, psShape->panPartStart[i], i - 1, psShape->panPartStart[i - 1]); 
+                psSHP->sHooks.Error( pszErrorMsg );
+                SHPDestroyObject(psShape);
+                return NULL;
+            }
 	}
 
 	nOffset = 44 + 8 + 4*nParts;
@@ -1612,7 +1773,7 @@
 /*      big enough, but really it will only occur for the Z shapes      */
 /*      (options), and the M shapes.                                    */
 /* -------------------------------------------------------------------- */
-        if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
+        if( nEntitySize >= nOffset + 16 + 8*nPoints )
         {
             memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
             memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
@@ -1640,15 +1801,60 @@
 	int32		nPoints;
 	int    		i, nOffset;
 
+        if ( 44 + 4 > nEntitySize )
+        {
+            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nEntitySize = %d",
+                     hEntity, nEntitySize); 
+            psSHP->sHooks.Error( pszErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
 	memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
+
 	if( bBigEndian ) SwapWord( 4, &nPoints );
 
+        if (nPoints < 0 || nPoints > 50 * 1000 * 1000)
+        {
+            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nPoints = %d",
+                     hEntity, nPoints); 
+            psSHP->sHooks.Error( pszErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
+
+        nRequiredSize = 48 + nPoints * 16;
+        if( psShape->nSHPType == SHPT_MULTIPOINTZ )
+        {
+            nRequiredSize += 16 + nPoints * 8;
+        }
+        if (nRequiredSize > nEntitySize)
+        {
+            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nPoints = %d, nEntitySize = %d",
+                     hEntity, nPoints, nEntitySize); 
+            psSHP->sHooks.Error( pszErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
+        
 	psShape->nVertices = nPoints;
         psShape->padfX = (double *) calloc(nPoints,sizeof(double));
         psShape->padfY = (double *) calloc(nPoints,sizeof(double));
         psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
         psShape->padfM = (double *) calloc(nPoints,sizeof(double));
 
+        if (psShape->padfX == NULL ||
+            psShape->padfY == NULL ||
+            psShape->padfZ == NULL ||
+            psShape->padfM == NULL)
+        {
+            snprintf(pszErrorMsg, 128,
+                     "Not enough memory to allocate requested memory (nPoints=%d) for shape %d. "
+                     "Probably broken SHP file", hEntity, nPoints );
+            psSHP->sHooks.Error( pszErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
+
 	for( i = 0; i < nPoints; i++ )
 	{
 	    memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
@@ -1700,7 +1906,7 @@
 /*      big enough, but really it will only occur for the Z shapes      */
 /*      (options), and the M shapes.                                    */
 /* -------------------------------------------------------------------- */
-        if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
+        if( nEntitySize >= nOffset + 16 + 8*nPoints )
         {
             memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
             memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
@@ -1733,6 +1939,14 @@
         psShape->padfZ = (double *) calloc(1,sizeof(double));
         psShape->padfM = (double *) calloc(1,sizeof(double));
 
+        if (20 + 8 + (( psShape->nSHPType == SHPT_POINTZ ) ? 8 : 0)> nEntitySize)
+        {
+            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nEntitySize = %d",
+                     hEntity, nEntitySize); 
+            psSHP->sHooks.Error( pszErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
 	memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 );
 	memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 );
 
@@ -1759,7 +1973,7 @@
 /*      big enough, but really it will only occur for the Z shapes      */
 /*      (options), and the M shapes.                                    */
 /* -------------------------------------------------------------------- */
-        if( psSHP->panRecSize[hEntity]+8 >= nOffset + 8 )
+        if( nEntitySize >= nOffset + 8 )
         {
             memcpy( psShape->padfM, psSHP->pabyRec + nOffset, 8 );
         
@@ -1985,7 +2199,7 @@
                     /* Rule #2:
                     * Test if edge-ray intersection is on the right from the test point (dfTestY,dfTestY)
                     */
-                    float const intersect = 
+                    double const intersect = 
                         ( psObject->padfX[iEdge+nVertStart]
                           + ( dfTestY - psObject->padfY[iEdge+nVertStart] ) 
                           / ( psObject->padfY[iNext+nVertStart] - psObject->padfY[iEdge+nVertStart] )



More information about the grass-commit mailing list