Changeset 14001

Show
Ignore:
Timestamp:
03/14/08 01:28:15 (2 months ago)
Author:
warmerdam
Message:

refresh from shapelib (#2218)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/1.5/gdal/ogr/ogrsf_frmts/shape/shpopen.c

    r13274 r14001  
    11/****************************************************************************** 
    2  * $Id: shpopen.c,v 1.57 2007/12/06 07:00:25 fwarmerdam Exp $ 
     2 * $Id: shpopen.c,v 1.59 2008/03/14 05:25:31 fwarmerdam Exp $ 
    33 * 
    44 * Project:  Shapelib 
     
    3535 * 
    3636 * $Log: shpopen.c,v $ 
     37 * Revision 1.59  2008/03/14 05:25:31  fwarmerdam 
     38 * Correct crash on buggy geometries (gdal #2218) 
     39 * 
     40 * Revision 1.58  2008/01/08 23:28:26  bram 
     41 * on line 2095, use a float instead of a double to avoid a compiler warning 
     42 * 
    3743 * Revision 1.57  2007/12/06 07:00:25  fwarmerdam 
    3844 * dbfopen now using SAHooks for fileio 
     
    226232#include <stdio.h> 
    227233 
    228 SHP_CVSID("$Id: shpopen.c,v 1.57 2007/12/06 07:00:25 fwarmerdam Exp $") 
     234SHP_CVSID("$Id: shpopen.c,v 1.59 2008/03/14 05:25:31 fwarmerdam Exp $") 
    229235 
    230236typedef unsigned char uchar; 
     
    14951501 
    14961502{ 
     1503    int                  nEntitySize, nRequiredSize; 
    14971504    SHPObject           *psShape; 
     1505    char                 pszErrorMsg[128]; 
    14981506 
    14991507/* -------------------------------------------------------------------- */ 
     
    15061514/*      Ensure our record buffer is large enough.                       */ 
    15071515/* -------------------------------------------------------------------- */ 
    1508     if( psSHP->panRecSize[hEntity]+8 > psSHP->nBufSize ) 
    1509     { 
    1510         psSHP->nBufSize = psSHP->panRecSize[hEntity]+8; 
    1511         psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,psSHP->nBufSize); 
     1516    nEntitySize = psSHP->panRecSize[hEntity]+8; 
     1517    if( nEntitySize > psSHP->nBufSize ) 
     1518    { 
     1519        psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,nEntitySize); 
    15121520        if (psSHP->pabyRec == NULL) 
    15131521        { 
    15141522            char szError[200]; 
     1523 
     1524            /* Reallocate previous successfull size for following features */ 
     1525            psSHP->pabyRec = malloc(psSHP->nBufSize); 
    15151526 
    15161527            sprintf( szError,  
     
    15201531            return NULL; 
    15211532        } 
     1533 
     1534        /* Only set new buffer size after successfull alloc */ 
     1535        psSHP->nBufSize = nEntitySize; 
     1536    } 
     1537 
     1538    /* In case we were not able to reallocate the buffer on a previous step */ 
     1539    if (psSHP->pabyRec == NULL) 
     1540    { 
     1541        return NULL; 
    15221542    } 
    15231543 
     
    15261546/* -------------------------------------------------------------------- */ 
    15271547    if( psSHP->sHooks.FSeek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0  
    1528         || psSHP->sHooks.FRead( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1,  
     1548        || psSHP->sHooks.FRead( psSHP->pabyRec, nEntitySize, 1,  
    15291549                  psSHP->fpSHP ) != 1 ) 
    15301550    { 
     
    15451565    psShape->bMeasureIsUsed = FALSE; 
    15461566 
     1567    if ( 8 + 4 > nEntitySize ) 
     1568    { 
     1569        snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nEntitySize = %d", 
     1570                    hEntity, nEntitySize);  
     1571        psSHP->sHooks.Error( pszErrorMsg ); 
     1572        SHPDestroyObject(psShape); 
     1573        return NULL; 
     1574    } 
    15471575    memcpy( &psShape->nSHPType, psSHP->pabyRec + 8, 4 ); 
     1576 
    15481577    if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) ); 
    15491578 
     
    15611590        int             i, nOffset; 
    15621591 
     1592        if ( 40 + 8 + 4 > nEntitySize ) 
     1593        { 
     1594            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nEntitySize = %d", 
     1595                     hEntity, nEntitySize);  
     1596            psSHP->sHooks.Error( pszErrorMsg ); 
     1597            SHPDestroyObject(psShape); 
     1598            return NULL; 
     1599        } 
    15631600/* -------------------------------------------------------------------- */ 
    15641601/*      Get the X/Y bounds.                                             */ 
     
    15841621        if( bBigEndian ) SwapWord( 4, &nParts ); 
    15851622 
    1586         if (nPoints < 0 || nParts < 0) 
    1587         { 
    1588 #ifdef USE_CPL 
    1589             CPLError(CE_Failure, CPLE_AppDefined, 
    1590                      "nPoints=%d, nParts=%d : bad value(s). Probably broken SHP file", nPoints, nParts ); 
    1591 #endif 
     1623        if (nPoints < 0 || nParts < 0 || 
     1624            nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000) 
     1625        { 
     1626            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d, nPoints=%d, nParts=%d.", 
     1627                        hEntity, nPoints, nParts); 
     1628            psSHP->sHooks.Error( pszErrorMsg ); 
     1629            SHPDestroyObject(psShape); 
     1630            return NULL; 
     1631        } 
     1632         
     1633        /* With the previous checks on nPoints and nParts, */ 
     1634        /* we should not overflow here and after */ 
     1635        /* since 50 M * (16 + 8 + 8) = 1 600 MB */ 
     1636        nRequiredSize = 44 + 8 + 4 * nParts + 16 * nPoints; 
     1637        if ( psShape->nSHPType == SHPT_POLYGONZ 
     1638            || psShape->nSHPType == SHPT_ARCZ 
     1639            || psShape->nSHPType == SHPT_MULTIPATCH ) 
     1640        { 
     1641            nRequiredSize += 16 + 8 * nPoints; 
     1642        } 
     1643        if( psShape->nSHPType == SHPT_MULTIPATCH ) 
     1644        { 
     1645            nRequiredSize += 4 * nParts; 
     1646        } 
     1647        if (nRequiredSize > nEntitySize) 
     1648        { 
     1649            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d, nPoints=%d, nParts=%d, nEntitySize=%d.", 
     1650                        hEntity, nPoints, nParts, nEntitySize); 
     1651            psSHP->sHooks.Error( pszErrorMsg ); 
    15921652            SHPDestroyObject(psShape); 
    15931653            return NULL; 
     
    16111671            psShape->panPartType == NULL) 
    16121672        { 
    1613 #ifdef USE_CPL 
    1614             CPLError(CE_Failure, CPLE_AppDefined, 
    1615                      "Not enough memory to allocate requested memory (nPoints=%d, nParts=%d). " 
    1616                      "Probably broken SHP file", nPoints, nParts ); 
    1617 #endif 
     1673            snprintf(pszErrorMsg, 128, 
     1674                     "Not enough memory to allocate requested memory (nPoints=%d, nParts=%d) for shape %d. " 
     1675                     "Probably broken SHP file", hEntity, nPoints, nParts ); 
     1676            psSHP->sHooks.Error( pszErrorMsg ); 
    16181677            SHPDestroyObject(psShape); 
    16191678            return NULL; 
     
    16301689        { 
    16311690            if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i ); 
     1691 
     1692            /* We check that the offset is inside the vertex array */ 
     1693            if (psShape->panPartStart[i] < 0 || 
     1694                psShape->panPartStart[i] >= psShape->nVertices) 
     1695            { 
     1696                snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : panPartStart[%d] = %d, nVertices = %d", 
     1697                         hEntity, i, psShape->panPartStart[i], psShape->nVertices);  
     1698                psSHP->sHooks.Error( pszErrorMsg ); 
     1699                SHPDestroyObject(psShape); 
     1700                return NULL; 
     1701            } 
     1702            if (i > 0 && psShape->panPartStart[i] <= psShape->panPartStart[i-1]) 
     1703            { 
     1704                snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : panPartStart[%d] = %d, panPartStart[%d] = %d", 
     1705                         hEntity, i, psShape->panPartStart[i], i - 1, psShape->panPartStart[i - 1]);  
     1706                psSHP->sHooks.Error( pszErrorMsg ); 
     1707                SHPDestroyObject(psShape); 
     1708                return NULL; 
     1709            } 
    16321710        } 
    16331711 
     
    16961774/*      (options), and the M shapes.                                    */ 
    16971775/* -------------------------------------------------------------------- */ 
    1698         if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints ) 
     1776        if( nEntitySize >= nOffset + 16 + 8*nPoints ) 
    16991777        { 
    17001778            memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); 
     
    17241802        int             i, nOffset; 
    17251803 
     1804        if ( 44 + 4 > nEntitySize ) 
     1805        { 
     1806            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nEntitySize = %d", 
     1807                     hEntity, nEntitySize);  
     1808            psSHP->sHooks.Error( pszErrorMsg ); 
     1809            SHPDestroyObject(psShape); 
     1810            return NULL; 
     1811        } 
    17261812        memcpy( &nPoints, psSHP->pabyRec + 44, 4 ); 
     1813 
    17271814        if( bBigEndian ) SwapWord( 4, &nPoints ); 
    17281815 
    1729         if (nPoints < 0) 
    1730         { 
    1731 #ifdef USE_CPL 
    1732             CPLError(CE_Failure, CPLE_AppDefined, 
    1733                      "nPoints=%d : bad value. Probably broken SHP file", nPoints ); 
    1734 #endif 
     1816        if (nPoints < 0 || nPoints > 50 * 1000 * 1000) 
     1817        { 
     1818            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nPoints = %d", 
     1819                     hEntity, nPoints);  
     1820            psSHP->sHooks.Error( pszErrorMsg ); 
     1821            SHPDestroyObject(psShape); 
     1822            return NULL; 
     1823        } 
     1824 
     1825        nRequiredSize = 48 + nPoints * 16; 
     1826        if( psShape->nSHPType == SHPT_MULTIPOINTZ ) 
     1827        { 
     1828            nRequiredSize += 16 + nPoints * 8; 
     1829        } 
     1830        if (nRequiredSize > nEntitySize) 
     1831        { 
     1832            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nPoints = %d, nEntitySize = %d", 
     1833                     hEntity, nPoints, nEntitySize);  
     1834            psSHP->sHooks.Error( pszErrorMsg ); 
    17351835            SHPDestroyObject(psShape); 
    17361836            return NULL; 
     
    17481848            psShape->padfM == NULL) 
    17491849        { 
    1750 #ifdef USE_CPL 
    1751             CPLError(CE_Failure, CPLE_AppDefined, 
    1752                      "Not enough memory to allocate requested memory (nPoints=%d). " 
    1753                      "Probably broken SHP file", nPoints ); 
    1754 #endif 
     1850            snprintf(pszErrorMsg, 128, 
     1851                     "Not enough memory to allocate requested memory (nPoints=%d) for shape %d. " 
     1852                     "Probably broken SHP file", hEntity, nPoints ); 
     1853            psSHP->sHooks.Error( pszErrorMsg ); 
    17551854            SHPDestroyObject(psShape); 
    17561855            return NULL; 
     
    18081907/*      (options), and the M shapes.                                    */ 
    18091908/* -------------------------------------------------------------------- */ 
    1810         if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints ) 
     1909        if( nEntitySize >= nOffset + 16 + 8*nPoints ) 
    18111910        { 
    18121911            memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); 
     
    18411940        psShape->padfM = (double *) calloc(1,sizeof(double)); 
    18421941 
     1942        if (20 + 8 + (( psShape->nSHPType == SHPT_POINTZ ) ? 8 : 0)> nEntitySize) 
     1943        { 
     1944            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nEntitySize = %d", 
     1945                     hEntity, nEntitySize);  
     1946            psSHP->sHooks.Error( pszErrorMsg ); 
     1947            SHPDestroyObject(psShape); 
     1948            return NULL; 
     1949        } 
    18431950        memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 ); 
    18441951        memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 ); 
     
    18671974/*      (options), and the M shapes.                                    */ 
    18681975/* -------------------------------------------------------------------- */ 
    1869         if( psSHP->panRecSize[hEntity]+8 >= nOffset + 8 ) 
     1976        if( nEntitySize >= nOffset + 8 ) 
    18701977        { 
    18711978            memcpy( psShape->padfM, psSHP->pabyRec + nOffset, 8 ); 
     
    20932200                    * Test if edge-ray intersection is on the right from the test point (dfTestY,dfTestY) 
    20942201                    */ 
    2095                     float const intersect =  
     2202                    double const intersect =  
    20962203                        ( psObject->padfX[iEdge+nVertStart] 
    20972204                          + ( dfTestY - psObject->padfY[iEdge+nVertStart] )