Changeset 14000
- Timestamp:
- 03/14/08 01:27:11 (4 months ago)
- Files:
-
- trunk/gdal/ogr/ogrsf_frmts/shape/shpopen.c (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/gdal/ogr/ogrsf_frmts/shape/shpopen.c
r13274 r14000 1 1 /****************************************************************************** 2 * $Id: shpopen.c,v 1.5 7 2007/12/06 07:00:25fwarmerdam Exp $2 * $Id: shpopen.c,v 1.59 2008/03/14 05:25:31 fwarmerdam Exp $ 3 3 * 4 4 * Project: Shapelib … … 35 35 * 36 36 * $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 * 37 43 * Revision 1.57 2007/12/06 07:00:25 fwarmerdam 38 44 * dbfopen now using SAHooks for fileio … … 226 232 #include <stdio.h> 227 233 228 SHP_CVSID("$Id: shpopen.c,v 1.5 7 2007/12/06 07:00:25fwarmerdam Exp $")234 SHP_CVSID("$Id: shpopen.c,v 1.59 2008/03/14 05:25:31 fwarmerdam Exp $") 229 235 230 236 typedef unsigned char uchar; … … 1495 1501 1496 1502 { 1503 int nEntitySize, nRequiredSize; 1497 1504 SHPObject *psShape; 1505 char pszErrorMsg[128]; 1498 1506 1499 1507 /* -------------------------------------------------------------------- */ … … 1506 1514 /* Ensure our record buffer is large enough. */ 1507 1515 /* -------------------------------------------------------------------- */ 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); 1512 1520 if (psSHP->pabyRec == NULL) 1513 1521 { 1514 1522 char szError[200]; 1523 1524 /* Reallocate previous successfull size for following features */ 1525 psSHP->pabyRec = malloc(psSHP->nBufSize); 1515 1526 1516 1527 sprintf( szError, … … 1520 1531 return NULL; 1521 1532 } 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; 1522 1542 } 1523 1543 … … 1526 1546 /* -------------------------------------------------------------------- */ 1527 1547 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, 1529 1549 psSHP->fpSHP ) != 1 ) 1530 1550 { … … 1545 1565 psShape->bMeasureIsUsed = FALSE; 1546 1566 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 } 1547 1575 memcpy( &psShape->nSHPType, psSHP->pabyRec + 8, 4 ); 1576 1548 1577 if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) ); 1549 1578 … … 1561 1590 int i, nOffset; 1562 1591 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 } 1563 1600 /* -------------------------------------------------------------------- */ 1564 1601 /* Get the X/Y bounds. */ … … 1584 1621 if( bBigEndian ) SwapWord( 4, &nParts ); 1585 1622 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 ); 1592 1652 SHPDestroyObject(psShape); 1593 1653 return NULL; … … 1611 1671 psShape->panPartType == NULL) 1612 1672 { 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 ); 1618 1677 SHPDestroyObject(psShape); 1619 1678 return NULL; … … 1630 1689 { 1631 1690 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 } 1632 1710 } 1633 1711 … … 1696 1774 /* (options), and the M shapes. */ 1697 1775 /* -------------------------------------------------------------------- */ 1698 if( psSHP->panRecSize[hEntity]+8>= nOffset + 16 + 8*nPoints )1776 if( nEntitySize >= nOffset + 16 + 8*nPoints ) 1699 1777 { 1700 1778 memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); … … 1724 1802 int i, nOffset; 1725 1803 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 } 1726 1812 memcpy( &nPoints, psSHP->pabyRec + 44, 4 ); 1813 1727 1814 if( bBigEndian ) SwapWord( 4, &nPoints ); 1728 1815 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 ); 1735 1835 SHPDestroyObject(psShape); 1736 1836 return NULL; … … 1748 1848 psShape->padfM == NULL) 1749 1849 { 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 ); 1755 1854 SHPDestroyObject(psShape); 1756 1855 return NULL; … … 1808 1907 /* (options), and the M shapes. */ 1809 1908 /* -------------------------------------------------------------------- */ 1810 if( psSHP->panRecSize[hEntity]+8>= nOffset + 16 + 8*nPoints )1909 if( nEntitySize >= nOffset + 16 + 8*nPoints ) 1811 1910 { 1812 1911 memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); … … 1841 1940 psShape->padfM = (double *) calloc(1,sizeof(double)); 1842 1941 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 } 1843 1950 memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 ); 1844 1951 memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 ); … … 1867 1974 /* (options), and the M shapes. */ 1868 1975 /* -------------------------------------------------------------------- */ 1869 if( psSHP->panRecSize[hEntity]+8>= nOffset + 8 )1976 if( nEntitySize >= nOffset + 8 ) 1870 1977 { 1871 1978 memcpy( psShape->padfM, psSHP->pabyRec + nOffset, 8 ); … … 2093 2200 * Test if edge-ray intersection is on the right from the test point (dfTestY,dfTestY) 2094 2201 */ 2095 floatconst intersect =2202 double const intersect = 2096 2203 ( psObject->padfX[iEdge+nVertStart] 2097 2204 + ( dfTestY - psObject->padfY[iEdge+nVertStart] )
