[Thuban-commits] r2887 - in branches/WIP-pyshapelib-Unicode/thuban/libraries: pyshapelib shapelib
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Thu Sep 17 20:57:49 CEST 2009
Author: bramz
Date: 2009-09-17 20:57:48 +0200 (Thu, 17 Sep 2009)
New Revision: 2887
Modified:
branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/ChangeLog
branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/dbflibmodule.c
branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/setup.py
branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/dbfopen.c
branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/safileio.c
branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/shapefil.h
branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/shpopen.c
branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/shptree.c
Log:
- forward porting shapelib to 1.3.0-a2 with snprintf patch
- add delete_field if DBFDeleteField is available in shapefil.h
Modified: branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/ChangeLog
===================================================================
--- branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/ChangeLog 2009-08-18 20:04:10 UTC (rev 2886)
+++ branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/ChangeLog 2009-09-17 18:57:48 UTC (rev 2887)
@@ -1,3 +1,8 @@
+2009-09-17 Bram de Greve <bram.degreve at bramz.net>
+
+ * dbflibmodule.c: add delete_field, if necessary API function is available
+ in shapefil.h
+
2009-08-15 Bram de Greve <bram.degreve at bramz.net>
* setup.py: add compiler flags to suppress a spurious warning
Modified: branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/dbflibmodule.c
===================================================================
--- branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/dbflibmodule.c 2009-08-18 20:04:10 UTC (rev 2886)
+++ branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/dbflibmodule.c 2009-09-17 18:57:48 UTC (rev 2887)
@@ -210,6 +210,33 @@
+static int check_field_index(DBFFileObject* self, int field)
+{
+ if (field < 0 || field >= DBFGetFieldCount(self->handle))
+ {
+ PyErr_Format(PyExc_IndexError,
+ "field index %d out of bounds (field count: %d)",
+ field, DBFGetFieldCount(self->handle));
+ return -1;
+ }
+ return field;
+}
+
+
+static int check_record_index(DBFFileObject* self, int record)
+{
+ if (record < 0 || record >= DBFGetRecordCount(self->handle))
+ {
+ PyErr_Format(PyExc_IndexError,
+ "record index %d out of bounds (record count: %d)",
+ record, DBFGetRecordCount(self->handle));
+ return -1;
+ }
+ return record;
+}
+
+
+
static PyObject* dbffile_field_info(DBFFileObject* self, PyObject* args)
{
char field_name[12];
@@ -217,6 +244,7 @@
PyObject* name_object = NULL;
if (!PyArg_ParseTuple(args, "i:field_info", &field)) return NULL;
+ if (check_field_index(self, field) < 0) return NULL;
field_name[0] = '\0';
field_type = DBFGetFieldInfo(self->handle, field, field_name, &width, &decimals);
@@ -259,6 +287,29 @@
+/* The method relies on the DBFDeleteField method which is not
+* available in shapelib <= 1.3.0. setup.py defines
+* HAVE_DELETE_FIELD's value depending on whether the function is
+* available in the shapelib version the code is compiled with.
+*/
+#if HAVE_DELETE_FIELD
+static PyObject* dbffile_delete_field(DBFFileObject* self, PyObject* args)
+{
+ int field;
+ if (!PyArg_ParseTuple(args, "i:field_info", &field)) return NULL;
+ if (check_field_index(self, field) < 0) return NULL;
+
+ if (!DBFDeleteField(self->handle, field))
+ {
+ PyErr_SetString(PyExc_RuntimeError, "failed to delete field.");
+ }
+
+ Py_RETURN_NONE;
+}
+#endif
+
+
+
/* Read one attribute from the dbf handle and return it as a new python object
*
* If an error occurs, set the appropriate Python exception and return
@@ -343,23 +394,9 @@
int record, field;
if (!PyArg_ParseTuple(args, "ii:read_attribute", &record, &field)) return NULL;
-
- if (record < 0 || record >= DBFGetRecordCount(self->handle))
- {
- PyErr_Format(PyExc_IndexError,
- "record index %d out of bounds (record count: %d)",
- record, DBFGetRecordCount(self->handle));
- return NULL;
- }
+ if (check_record_index(self, record) < 0) return NULL;
+ if (check_field_index(self, field) < 0) return NULL;
- if (field < 0 || field >= DBFGetFieldCount(self->handle))
- {
- PyErr_Format(PyExc_IndexError,
- "field index %d out of bounds (field count: %d)",
- field, DBFGetFieldCount(self->handle));
- return NULL;
- }
-
return do_read_attribute(self, record, field, NULL);
}
@@ -379,15 +416,8 @@
PyObject *value = NULL;
if (!PyArg_ParseTuple(args, "i:read_record", &record)) return NULL;
+ if (check_record_index(self, record) < 0) return NULL;
- if (record < 0 || record >= DBFGetRecordCount(self->handle))
- {
- PyErr_Format(PyExc_IndexError,
- "record index %d out of bounds (record count: %d)",
- record, DBFGetRecordCount(self->handle));
- return NULL;
- }
-
dict = PyDict_New();
if (!dict) return NULL;
@@ -474,15 +504,8 @@
int type;
if (!PyArg_ParseTuple(args, "iiO:write_attribute", &record, &field, &value)) return NULL;
+ if (check_field_index(self, field) < 0) return NULL;
- if (field < 0 || field >= DBFGetFieldCount(self->handle))
- {
- PyErr_Format(PyExc_ValueError,
- "field index %d out of bounds (field count: %d)",
- field, DBFGetFieldCount(self->handle));
- return NULL;
- }
-
type = DBFGetFieldInfo(self->handle, field, NULL, NULL, NULL);
if (!do_write_attribute(self, record, field, type, value)) return NULL;
Py_RETURN_NONE;
@@ -627,6 +650,11 @@
"- name: the name of the field as a string\n"
"- width: the width of the field as a number of characters\n"
"- decimals: the number of decimal digits" },
+#if HAVE_DELETE_FIELD
+ {"delete_field", (PyCFunction)dbffile_delete_field, METH_NOARGS,
+ "delete_field(field_index) -> None"
+ "removes an entire column"},
+#endif
{"read_attribute", (PyCFunction)dbffile_read_attribute, METH_VARARGS,
"read_attribute(record_index, field_index) -> value\n\n"
"returns the value of one field of a record"},
Modified: branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/setup.py
===================================================================
--- branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/setup.py 2009-08-18 20:04:10 UTC (rev 2886)
+++ branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/setup.py 2009-09-17 18:57:48 UTC (rev 2887)
@@ -74,6 +74,7 @@
return [
("HAVE_UPDATE_HEADER", have("DBFUpdateHeader")),
("HAVE_CODE_PAGE", have("DBFGetCodePage")),
+ ("HAVE_DELETE_FIELD", have("DBFDeleteField")),
("DISABLE_CVSID", "1")]
macros = determine_macros()
Modified: branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/dbfopen.c
===================================================================
--- branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/dbfopen.c 2009-08-18 20:04:10 UTC (rev 2886)
+++ branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/dbfopen.c 2009-09-17 18:57:48 UTC (rev 2887)
@@ -34,6 +34,12 @@
******************************************************************************
*
* $Log: dbfopen.c,v $
+ * Revision 1.83 2008-11-12 14:28:15 fwarmerdam
+ * DBFCreateField() now works on files with records
+ *
+ * Revision 1.82 2008/11/11 17:47:09 fwarmerdam
+ * added DBFDeleteField() function
+ *
* Revision 1.81 2008/01/03 17:48:13 bram
* in DBFCreate, use default code page LDID/87 (= 0x57, ANSI)
* instead of LDID/3. This seems to be the same as what ESRI
@@ -739,8 +745,7 @@
/************************************************************************/
/* DBFAddField() */
/* */
-/* Add a field to a newly created .dbf file before any records */
-/* are written. */
+/* Add a field to a newly created .dbf or to an existing one */
/************************************************************************/
int SHPAPI_CALL
@@ -775,22 +780,23 @@
{
char *pszFInfo;
int i;
+ int nOldRecordLength, nOldHeaderLength;
+ char *pszRecord;
+ char chFieldFill;
+ SAOffset nRecordOffset;
/* -------------------------------------------------------------------- */
/* Do some checking to ensure we can add records to this file. */
/* -------------------------------------------------------------------- */
- if( psDBF->nRecords > 0 )
- return( -1 );
-
- if( !psDBF->bNoHeader )
- return( -1 );
-
if( nWidth < 1 )
return -1;
if( nWidth > 255 )
nWidth = 255;
+ nOldRecordLength = psDBF->nRecordLength;
+ nOldHeaderLength = psDBF->nHeaderLength;
+
/* -------------------------------------------------------------------- */
/* SfRealloc all the arrays larger to hold the additional field */
/* information. */
@@ -855,6 +861,59 @@
psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
psDBF->nRecordLength);
+ /* we're done if dealing with new .dbf */
+ if( psDBF->bNoHeader )
+ return( psDBF->nFields - 1 );
+
+/* -------------------------------------------------------------------- */
+/* For existing .dbf file, shift records */
+/* -------------------------------------------------------------------- */
+
+ /* alloc record */
+ pszRecord = (char *) malloc(sizeof(char) * psDBF->nRecordLength);
+
+ switch (chType)
+ {
+ case 'N':
+ case 'F':
+ chFieldFill = '*';
+ break;
+ case 'D':
+ chFieldFill = '0';
+ break;
+ case 'L':
+ chFieldFill = '?';
+ break;
+ default:
+ chFieldFill = ' ';
+ break;
+ }
+
+ for (i = psDBF->nRecords-1; i >= 0; --i)
+ {
+ nRecordOffset = nOldRecordLength * (SAOffset) i + nOldHeaderLength;
+
+ /* load record */
+ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+ psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
+
+ /* set new field's value to NULL */
+ memset(pszRecord + nOldRecordLength, chFieldFill, nWidth);
+
+ nRecordOffset = psDBF->nRecordLength * (SAOffset) i + psDBF->nHeaderLength;
+
+ /* move record to the new place*/
+ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+ psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
+ }
+
+ /* free record */
+ free(pszRecord);
+
+ /* force update of header with new header, record length and new field */
+ psDBF->bNoHeader = TRUE;
+ DBFUpdateHeader( psDBF );
+
return( psDBF->nFields-1 );
}
@@ -1702,3 +1761,111 @@
return NULL;
return psDBF->pszCodePage;
}
+
+/************************************************************************/
+/* DBFDeleteField() */
+/* */
+/* Remove a field from a .dbf file */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFDeleteField(DBFHandle psDBF, int iField)
+{
+ int nOldRecordLength, nOldHeaderLength;
+ int nDeletedFieldOffset, nDeletedFieldSize;
+ SAOffset nRecordOffset;
+ char* pszRecord;
+ int i, iRecord;
+
+ if (iField < 0 || iField >= psDBF->nFields)
+ return FALSE;
+
+ /* make sure that everything is written in .dbf */
+ if( !DBFFlushRecord( psDBF ) )
+ return FALSE;
+
+ /* get information about field to be deleted */
+ nOldRecordLength = psDBF->nRecordLength;
+ nOldHeaderLength = psDBF->nHeaderLength;
+ nDeletedFieldOffset = psDBF->panFieldOffset[iField];
+ nDeletedFieldSize = psDBF->panFieldSize[iField];
+
+ /* update fields info */
+ for (i = iField + 1; i < psDBF->nFields; i++)
+ {
+ psDBF->panFieldOffset[i-1] = psDBF->panFieldOffset[i] - nDeletedFieldSize;
+ psDBF->panFieldSize[i-1] = psDBF->panFieldSize[i];
+ psDBF->panFieldDecimals[i-1] = psDBF->panFieldDecimals[i];
+ psDBF->pachFieldType[i-1] = psDBF->pachFieldType[i];
+ }
+
+ /* resize fields arrays */
+ psDBF->nFields--;
+
+ psDBF->panFieldOffset = (int *)
+ SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
+
+ psDBF->panFieldSize = (int *)
+ SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
+
+ psDBF->panFieldDecimals = (int *)
+ SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
+
+ psDBF->pachFieldType = (char *)
+ SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );
+
+ /* update header information */
+ psDBF->nHeaderLength -= 32;
+ psDBF->nRecordLength -= nDeletedFieldSize;
+
+ /* overwrite field information in header */
+ memcpy(psDBF->pszHeader + iField*32,
+ psDBF->pszHeader + (iField+1)*32,
+ sizeof(char) * (psDBF->nFields - iField)*32);
+
+ psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader,psDBF->nFields*32);
+
+ /* update size of current record appropriately */
+ psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
+ psDBF->nRecordLength);
+
+ /* we're done if we're dealing with not yet created .dbf */
+ if ( psDBF->bNoHeader && psDBF->nRecords == 0 )
+ return TRUE;
+
+ /* force update of header with new header and record length */
+ psDBF->bNoHeader = TRUE;
+ DBFUpdateHeader( psDBF );
+
+ /* alloc record */
+ pszRecord = (char *) malloc(sizeof(char) * nOldRecordLength);
+
+ /* shift records to their new positions */
+ for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
+ {
+ nRecordOffset =
+ nOldRecordLength * (SAOffset) iRecord + nOldHeaderLength;
+
+ /* load record */
+ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+ psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
+
+ nRecordOffset =
+ psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
+
+ /* move record in two steps */
+ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+ psDBF->sHooks.FWrite( pszRecord, nDeletedFieldOffset, 1, psDBF->fp );
+ psDBF->sHooks.FWrite( pszRecord + nDeletedFieldOffset + nDeletedFieldSize,
+ nOldRecordLength - nDeletedFieldOffset - nDeletedFieldSize,
+ 1, psDBF->fp );
+
+ }
+
+ /* TODO: truncate file */
+
+ /* free record */
+ free(pszRecord);
+
+ return TRUE;
+}
Modified: branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/safileio.c
===================================================================
--- branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/safileio.c 2009-08-18 20:04:10 UTC (rev 2886)
+++ branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/safileio.c 2009-09-17 18:57:48 UTC (rev 2887)
@@ -1,281 +1,286 @@
-/******************************************************************************
- * $Id: safileio.c,v 1.3 2007/12/18 18:28:11 bram Exp $
- *
- * Project: Shapelib
- * Purpose: Default implementation of file io based on stdio.
- * Author: Frank Warmerdam, warmerdam at pobox.com
- *
- ******************************************************************************
- * Copyright (c) 2007, Frank Warmerdam
- *
- * This software is available under the following "MIT Style" license,
- * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This
- * option is discussed in more detail in shapelib.html.
- *
- * --
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- ******************************************************************************
- *
- * $Log: safileio.c,v $
- * Revision 1.3 2007/12/18 18:28:11 bram
- * - create hook for client specific atof (bugzilla ticket 1615)
- * - check for NULL handle before closing cpCPG file, and close after reading.
- *
- * Revision 1.2 2007/12/15 20:25:30 bram
- * dbfopen.c now reads the Code Page information from the DBF file, and exports
- * this information as a string through the DBFGetCodePage function. This is
- * either the number from the LDID header field ("LDID/<number>") or as the
- * content of an accompanying .CPG file. When creating a DBF file, the code can
- * be set using DBFCreateEx.
- *
- * Revision 1.1 2007/12/06 06:56:41 fwarmerdam
- * new
- *
- */
-
-#include "shapefil.h"
-
-#include <math.h>
-#include <limits.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-SHP_CVSID("$Id: safileio.c,v 1.3 2007/12/18 18:28:11 bram Exp $");
-
-#ifdef SHPAPI_UTF8_HOOKS
-# ifdef SHPAPI_WINDOWS
-# define WIN32_LEAN_AND_MEAN
-# define NOMINMAX
-# include <windows.h>
-# pragma comment(lib, "kernel32.lib")
-# endif
-#endif
-
-/************************************************************************/
-/* SADFOpen() */
-/************************************************************************/
-
-SAFile SADFOpen( const char *pszFilename, const char *pszAccess )
-
-{
- return (SAFile) fopen( pszFilename, pszAccess );
-}
-
-/************************************************************************/
-/* SADFRead() */
-/************************************************************************/
-
-SAOffset SADFRead( void *p, SAOffset size, SAOffset nmemb, SAFile file )
-
-{
- return (SAOffset) fread( p, (size_t) size, (size_t) nmemb,
- (FILE *) file );
-}
-
-/************************************************************************/
-/* SADFWrite() */
-/************************************************************************/
-
-SAOffset SADFWrite( void *p, SAOffset size, SAOffset nmemb, SAFile file )
-
-{
- return (SAOffset) fwrite( p, (size_t) size, (size_t) nmemb,
- (FILE *) file );
-}
-
-/************************************************************************/
-/* SADFSeek() */
-/************************************************************************/
-
-SAOffset SADFSeek( SAFile file, SAOffset offset, int whence )
-
-{
- return (SAOffset) fseek( (FILE *) file, (long) offset, whence );
-}
-
-/************************************************************************/
-/* SADFTell() */
-/************************************************************************/
-
-SAOffset SADFTell( SAFile file )
-
-{
- return (SAOffset) ftell( (FILE *) file );
-}
-
-/************************************************************************/
-/* SADFFlush() */
-/************************************************************************/
-
-int SADFFlush( SAFile file )
-
-{
- return fflush( (FILE *) file );
-}
-
-/************************************************************************/
-/* SADFClose() */
-/************************************************************************/
-
-int SADFClose( SAFile file )
-
-{
- return fclose( (FILE *) file );
-}
-
-/************************************************************************/
-/* SADFClose() */
-/************************************************************************/
-
-int SADRemove( const char *filename )
-
-{
- return remove( filename );
-}
-
-/************************************************************************/
-/* SADError() */
-/************************************************************************/
-
-void SADError( const char *message )
-
-{
- fprintf( stderr, "%s\n", message );
-}
-
-/************************************************************************/
-/* SASetupDefaultHooks() */
-/************************************************************************/
-
-void SASetupDefaultHooks( SAHooks *psHooks )
-
-{
- psHooks->FOpen = SADFOpen;
- psHooks->FRead = SADFRead;
- psHooks->FWrite = SADFWrite;
- psHooks->FSeek = SADFSeek;
- psHooks->FTell = SADFTell;
- psHooks->FFlush = SADFFlush;
- psHooks->FClose = SADFClose;
- psHooks->Remove = SADRemove;
-
- psHooks->Error = SADError;
- psHooks->Atof = atof;
-}
-
-
-
-
-#ifdef SHPAPI_WINDOWS
-
-/************************************************************************/
-/* Utf8ToWideChar */
-/************************************************************************/
-
-const wchar_t* Utf8ToWideChar( const char *pszFilename )
-{
- int nMulti, nWide;
- wchar_t *pwszFileName;
-
- nMulti = strlen(pszFilename) + 1;
- nWide = MultiByteToWideChar( CP_UTF8, 0, pszFilename, nMulti, 0, 0);
- if( nWide == 0 )
- {
- return NULL;
- }
- pwszFileName = (wchar_t*) malloc(nWide * sizeof(wchar_t));
- if ( pwszFileName == NULL )
- {
- return NULL;
- }
- if( MultiByteToWideChar( CP_UTF8, 0, pszFilename, nMulti, pwszFileName, nWide ) == 0 )
- {
- free( pwszFileName );
- return NULL;
- }
- return pwszFileName;
-}
-
-/************************************************************************/
-/* SAUtf8WFOpen */
-/************************************************************************/
-
-SAFile SAUtf8WFOpen( const char *pszFilename, const char *pszAccess )
-{
- SAFile file = NULL;
- const wchar_t *pwszFileName, *pwszAccess;
- pwszFileName = Utf8ToWideChar( pszFilename );
- pwszAccess = Utf8ToWideChar( pszAccess );
- if( pwszFileName != NULL && pwszFileName != NULL)
- {
- file = (SAFile) _wfopen( pwszFileName, pwszAccess );
- }
- free ((wchar_t*) pwszFileName);
- free ((wchar_t*) pwszAccess);
- return file;
-}
-
-/************************************************************************/
-/* SAUtf8WRemove() */
-/************************************************************************/
-
-int SAUtf8WRemove( const char *pszFilename )
-{
- const wchar_t *pwszFileName = Utf8ToWideChar( pszFilename );
- int rc = -1;
- if( pwszFileName != NULL )
- {
- rc = _wremove( pwszFileName );
- }
- free ((wchar_t*) pwszFileName);
- return rc;
-}
-
-#endif
-
-#ifdef SHPAPI_UTF8_HOOKS
-
-/************************************************************************/
-/* SASetupUtf8Hooks() */
-/************************************************************************/
-
-void SASetupUtf8Hooks( SAHooks *psHooks )
-{
-#ifdef SHPAPI_WINDOWS
- psHooks->FOpen = SAUtf8WFOpen;
- psHooks->Remove = SAUtf8WRemove;
-#else
- psHooks->FOpen = SADFOpen;
- psHooks->Remove = SADRemove;
-#endif
- psHooks->FRead = SADFRead;
- psHooks->FWrite = SADFWrite;
- psHooks->FSeek = SADFSeek;
- psHooks->FTell = SADFTell;
- psHooks->FFlush = SADFFlush;
- psHooks->FClose = SADFClose;
-
- psHooks->Error = SADError;
- psHooks->Atof = atof;
-}
-
-#endif
+/******************************************************************************
+ * $Id: safileio.c,v 1.4 2008-01-16 20:05:14 bram Exp $
+ *
+ * Project: Shapelib
+ * Purpose: Default implementation of file io based on stdio.
+ * Author: Frank Warmerdam, warmerdam at pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2007, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: safileio.c,v $
+ * Revision 1.4 2008-01-16 20:05:14 bram
+ * Add file hooks that accept UTF-8 encoded filenames on some platforms. Use SASetupUtf8Hooks
+ * tosetup the hooks and check SHPAPI_UTF8_HOOKS for its availability. Currently, this
+ * is only available on the Windows platform that decodes the UTF-8 filenames to wide
+ * character strings and feeds them to _wfopen and _wremove.
+ *
+ * Revision 1.3 2007/12/18 18:28:11 bram
+ * - create hook for client specific atof (bugzilla ticket 1615)
+ * - check for NULL handle before closing cpCPG file, and close after reading.
+ *
+ * Revision 1.2 2007/12/15 20:25:30 bram
+ * dbfopen.c now reads the Code Page information from the DBF file, and exports
+ * this information as a string through the DBFGetCodePage function. This is
+ * either the number from the LDID header field ("LDID/<number>") or as the
+ * content of an accompanying .CPG file. When creating a DBF file, the code can
+ * be set using DBFCreateEx.
+ *
+ * Revision 1.1 2007/12/06 06:56:41 fwarmerdam
+ * new
+ *
+ */
+
+#include "shapefil.h"
+
+#include <math.h>
+#include <limits.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+SHP_CVSID("$Id: safileio.c,v 1.4 2008-01-16 20:05:14 bram Exp $");
+
+#ifdef SHPAPI_UTF8_HOOKS
+# ifdef SHPAPI_WINDOWS
+# define WIN32_LEAN_AND_MEAN
+# define NOMINMAX
+# include <windows.h>
+# pragma comment(lib, "kernel32.lib")
+# endif
+#endif
+
+/************************************************************************/
+/* SADFOpen() */
+/************************************************************************/
+
+SAFile SADFOpen( const char *pszFilename, const char *pszAccess )
+
+{
+ return (SAFile) fopen( pszFilename, pszAccess );
+}
+
+/************************************************************************/
+/* SADFRead() */
+/************************************************************************/
+
+SAOffset SADFRead( void *p, SAOffset size, SAOffset nmemb, SAFile file )
+
+{
+ return (SAOffset) fread( p, (size_t) size, (size_t) nmemb,
+ (FILE *) file );
+}
+
+/************************************************************************/
+/* SADFWrite() */
+/************************************************************************/
+
+SAOffset SADFWrite( void *p, SAOffset size, SAOffset nmemb, SAFile file )
+
+{
+ return (SAOffset) fwrite( p, (size_t) size, (size_t) nmemb,
+ (FILE *) file );
+}
+
+/************************************************************************/
+/* SADFSeek() */
+/************************************************************************/
+
+SAOffset SADFSeek( SAFile file, SAOffset offset, int whence )
+
+{
+ return (SAOffset) fseek( (FILE *) file, (long) offset, whence );
+}
+
+/************************************************************************/
+/* SADFTell() */
+/************************************************************************/
+
+SAOffset SADFTell( SAFile file )
+
+{
+ return (SAOffset) ftell( (FILE *) file );
+}
+
+/************************************************************************/
+/* SADFFlush() */
+/************************************************************************/
+
+int SADFFlush( SAFile file )
+
+{
+ return fflush( (FILE *) file );
+}
+
+/************************************************************************/
+/* SADFClose() */
+/************************************************************************/
+
+int SADFClose( SAFile file )
+
+{
+ return fclose( (FILE *) file );
+}
+
+/************************************************************************/
+/* SADFClose() */
+/************************************************************************/
+
+int SADRemove( const char *filename )
+
+{
+ return remove( filename );
+}
+
+/************************************************************************/
+/* SADError() */
+/************************************************************************/
+
+void SADError( const char *message )
+
+{
+ fprintf( stderr, "%s\n", message );
+}
+
+/************************************************************************/
+/* SASetupDefaultHooks() */
+/************************************************************************/
+
+void SASetupDefaultHooks( SAHooks *psHooks )
+
+{
+ psHooks->FOpen = SADFOpen;
+ psHooks->FRead = SADFRead;
+ psHooks->FWrite = SADFWrite;
+ psHooks->FSeek = SADFSeek;
+ psHooks->FTell = SADFTell;
+ psHooks->FFlush = SADFFlush;
+ psHooks->FClose = SADFClose;
+ psHooks->Remove = SADRemove;
+
+ psHooks->Error = SADError;
+ psHooks->Atof = atof;
+}
+
+
+
+
+#ifdef SHPAPI_WINDOWS
+
+/************************************************************************/
+/* Utf8ToWideChar */
+/************************************************************************/
+
+const wchar_t* Utf8ToWideChar( const char *pszFilename )
+{
+ int nMulti, nWide;
+ wchar_t *pwszFileName;
+
+ nMulti = strlen(pszFilename) + 1;
+ nWide = MultiByteToWideChar( CP_UTF8, 0, pszFilename, nMulti, 0, 0);
+ if( nWide == 0 )
+ {
+ return NULL;
+ }
+ pwszFileName = (wchar_t*) malloc(nWide * sizeof(wchar_t));
+ if ( pwszFileName == NULL )
+ {
+ return NULL;
+ }
+ if( MultiByteToWideChar( CP_UTF8, 0, pszFilename, nMulti, pwszFileName, nWide ) == 0 )
+ {
+ free( pwszFileName );
+ return NULL;
+ }
+ return pwszFileName;
+}
+
+/************************************************************************/
+/* SAUtf8WFOpen */
+/************************************************************************/
+
+SAFile SAUtf8WFOpen( const char *pszFilename, const char *pszAccess )
+{
+ SAFile file = NULL;
+ const wchar_t *pwszFileName, *pwszAccess;
+ pwszFileName = Utf8ToWideChar( pszFilename );
+ pwszAccess = Utf8ToWideChar( pszAccess );
+ if( pwszFileName != NULL && pwszFileName != NULL)
+ {
+ file = (SAFile) _wfopen( pwszFileName, pwszAccess );
+ }
+ free ((wchar_t*) pwszFileName);
+ free ((wchar_t*) pwszAccess);
+ return file;
+}
+
+/************************************************************************/
+/* SAUtf8WRemove() */
+/************************************************************************/
+
+int SAUtf8WRemove( const char *pszFilename )
+{
+ const wchar_t *pwszFileName = Utf8ToWideChar( pszFilename );
+ int rc = -1;
+ if( pwszFileName != NULL )
+ {
+ rc = _wremove( pwszFileName );
+ }
+ free ((wchar_t*) pwszFileName);
+ return rc;
+}
+
+#endif
+
+#ifdef SHPAPI_UTF8_HOOKS
+
+/************************************************************************/
+/* SASetupUtf8Hooks() */
+/************************************************************************/
+
+void SASetupUtf8Hooks( SAHooks *psHooks )
+{
+#ifdef SHPAPI_WINDOWS
+ psHooks->FOpen = SAUtf8WFOpen;
+ psHooks->Remove = SAUtf8WRemove;
+#else
+# error "no implementations of UTF-8 hooks available for this platform"
+#endif
+ psHooks->FRead = SADFRead;
+ psHooks->FWrite = SADFWrite;
+ psHooks->FSeek = SADFSeek;
+ psHooks->FTell = SADFTell;
+ psHooks->FFlush = SADFFlush;
+ psHooks->FClose = SADFClose;
+
+ psHooks->Error = SADError;
+ psHooks->Atof = atof;
+}
+
+#endif
Modified: branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/shapefil.h
===================================================================
--- branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/shapefil.h 2009-08-18 20:04:10 UTC (rev 2886)
+++ branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/shapefil.h 2009-09-17 18:57:48 UTC (rev 2887)
@@ -37,6 +37,12 @@
******************************************************************************
*
* $Log: shapefil.h,v $
+ * Revision 1.46 2008-11-12 14:28:15 fwarmerdam
+ * DBFCreateField() now works on files with records
+ *
+ * Revision 1.45 2008/11/11 17:47:10 fwarmerdam
+ * added DBFDeleteField() function
+ *
* Revision 1.44 2008/01/16 20:05:19 bram
* Add file hooks that accept UTF-8 encoded filenames on some platforms. Use SASetupUtf8Hooks
* tosetup the hooks and check SHPAPI_UTF8_HOOKS for its availability. Currently, this
@@ -124,6 +130,7 @@
#ifdef USE_CPL
#include "cpl_error.h"
+#include "cpl_vsi.h"
#endif
#ifdef __cplusplus
@@ -534,6 +541,9 @@
DBFAddNativeFieldType( DBFHandle hDBF, const char * pszFieldName,
char chType, int nWidth, int nDecimals );
+int SHPAPI_CALL
+ DBFDeleteField( DBFHandle hDBF, int iField );
+
DBFFieldType SHPAPI_CALL
DBFGetFieldInfo( DBFHandle psDBF, int iField,
char * pszFieldName, int * pnWidth, int * pnDecimals );
Modified: branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/shpopen.c
===================================================================
--- branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/shpopen.c 2009-08-18 20:04:10 UTC (rev 2886)
+++ branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/shpopen.c 2009-09-17 18:57:48 UTC (rev 2887)
@@ -34,6 +34,9 @@
******************************************************************************
*
* $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
*
@@ -249,6 +252,12 @@
# define MAX(a,b) ((a>b) ? a : b)
#endif
+#if defined(WIN32) || defined(_WIN32)
+# ifndef snprintf
+# define snprintf _snprintf
+# endif
+#endif
+
static int bBigEndian;
@@ -1497,7 +1506,9 @@
SHPReadObject( SHPHandle psSHP, int hEntity )
{
+ int nEntitySize, nRequiredSize;
SHPObject *psShape;
+ char pszErrorMsg[128];
/* -------------------------------------------------------------------- */
/* Validate the record/entity number. */
@@ -1508,27 +1519,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( psSHP->sHooks.FSeek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0
- || psSHP->sHooks.FRead( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1,
+ || psSHP->sHooks.FRead( psSHP->pabyRec, nEntitySize, 1,
psSHP->fpSHP ) != 1 )
{
/*
@@ -1547,7 +1570,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) );
/* ==================================================================== */
@@ -1563,6 +1595,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. */
/* -------------------------------------------------------------------- */
@@ -1586,15 +1626,38 @@
if( bBigEndian ) SwapWord( 4, &nPoints );
if( bBigEndian ) SwapWord( 4, &nParts );
- if (nPoints < 0 || nParts < 0)
+ if (nPoints < 0 || nParts < 0 ||
+ nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000)
{
-#ifdef USE_CPL
- CPLError(CE_Failure, CPLE_AppDefined,
- "nPoints=%d, nParts=%d : bad value(s). Probably broken SHP file", nPoints, nParts );
-#endif
+ 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));
@@ -1613,11 +1676,10 @@
psShape->panPartStart == NULL ||
psShape->panPartType == NULL)
{
-#ifdef USE_CPL
- CPLError(CE_Failure, CPLE_AppDefined,
- "Not enough memory to allocate requested memory (nPoints=%d, nParts=%d). "
- "Probably broken SHP file", nPoints, nParts );
-#endif
+ 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;
}
@@ -1632,6 +1694,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;
@@ -1698,7 +1779,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 );
@@ -1726,18 +1807,40 @@
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)
+ if (nPoints < 0 || nPoints > 50 * 1000 * 1000)
{
-#ifdef USE_CPL
- CPLError(CE_Failure, CPLE_AppDefined,
- "nPoints=%d : bad value. Probably broken SHP file", nPoints );
-#endif
+ 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));
@@ -1750,11 +1853,10 @@
psShape->padfZ == NULL ||
psShape->padfM == NULL)
{
-#ifdef USE_CPL
- CPLError(CE_Failure, CPLE_AppDefined,
- "Not enough memory to allocate requested memory (nPoints=%d). "
- "Probably broken SHP file", nPoints );
-#endif
+ 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;
}
@@ -1810,7 +1912,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 );
@@ -1843,6 +1945,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 );
@@ -1869,7 +1979,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 );
Modified: branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/shptree.c
===================================================================
--- branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/shptree.c 2009-08-18 20:04:10 UTC (rev 2886)
+++ branches/WIP-pyshapelib-Unicode/thuban/libraries/shapelib/shptree.c 2009-09-17 18:57:48 UTC (rev 2887)
@@ -34,6 +34,9 @@
******************************************************************************
*
* $Log: shptree.c,v $
+ * Revision 1.12 2008-11-12 15:39:50 fwarmerdam
+ * improve safety in face of buggy .shp file.
+ *
* Revision 1.11 2007/10/27 03:31:14 fwarmerdam
* limit default depth of tree to 12 levels (gdal ticket #1594)
*
@@ -259,8 +262,11 @@
SHPObject *psShape;
psShape = SHPReadObject( hSHP, iShape );
- SHPTreeAddShapeId( psTree, psShape );
- SHPDestroyObject( psShape );
+ if( psShape != NULL )
+ {
+ SHPTreeAddShapeId( psTree, psShape );
+ SHPDestroyObject( psShape );
+ }
}
}
More information about the Thuban-commits
mailing list