PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ if() [8/10]

Definition at line 2064 of file shpopen.c.

2070  {
2071  int32 nPoints, nParts;
2072  int i, nOffset;
2073  unsigned char* pBuffer = SHPLIB_NULLPTR;
2074  unsigned char** ppBuffer = SHPLIB_NULLPTR;
2075 
2076  if ( 40 + 8 + 4 > nEntitySize )
2077  {
2078  snprintf(szErrorMsg, sizeof(szErrorMsg),
2079  "Corrupted .shp file : shape %d : nEntitySize = %d",
2080  hEntity, nEntitySize);
2081  szErrorMsg[sizeof(szErrorMsg)-1] = '\0';
2082  psSHP->sHooks.Error( szErrorMsg );
2084  return SHPLIB_NULLPTR;
2085  }
2086 /* -------------------------------------------------------------------- */
2087 /* Get the X/Y bounds. */
2088 /* -------------------------------------------------------------------- */
2089  memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8 );
2090  memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 );
2091  memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
2092  memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );
2093 
2094  if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
2095  if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
2096  if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
2097  if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
2098 
2099 /* -------------------------------------------------------------------- */
2100 /* Extract part/point count, and build vertex and part arrays */
2101 /* to proper size. */
2102 /* -------------------------------------------------------------------- */
2103  memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
2104  memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
2105 
2106  if( bBigEndian ) SwapWord( 4, &nPoints );
2107  if( bBigEndian ) SwapWord( 4, &nParts );
2108 
2109  /* nPoints and nParts are unsigned */
2110  if (/* nPoints < 0 || nParts < 0 || */
2111  nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000)
2112  {
2113  snprintf(szErrorMsg, sizeof(szErrorMsg),
2114  "Corrupted .shp file : shape %d, nPoints=%u, nParts=%u.",
2115  hEntity, nPoints, nParts);
2116  szErrorMsg[sizeof(szErrorMsg)-1] = '\0';
2117  psSHP->sHooks.Error( szErrorMsg );
2119  return SHPLIB_NULLPTR;
2120  }
2121 
2122  /* With the previous checks on nPoints and nParts, */
2123  /* we should not overflow here and after */
2124  /* since 50 M * (16 + 8 + 8) = 1 600 MB */
2125  nRequiredSize = 44 + 8 + 4 * nParts + 16 * nPoints;
2126  if ( psShape->nSHPType == SHPT_POLYGONZ
2127  || psShape->nSHPType == SHPT_ARCZ
2128  || psShape->nSHPType == SHPT_MULTIPATCH )
2129  {
2130  nRequiredSize += 16 + 8 * nPoints;
2131  }
2132  if( psShape->nSHPType == SHPT_MULTIPATCH )
2133  {
2134  nRequiredSize += 4 * nParts;
2135  }
2136  if (nRequiredSize > nEntitySize)
2137  {
2138  snprintf(szErrorMsg, sizeof(szErrorMsg),
2139  "Corrupted .shp file : shape %d, nPoints=%u, nParts=%u, nEntitySize=%d.",
2140  hEntity, nPoints, nParts, nEntitySize);
2141  szErrorMsg[sizeof(szErrorMsg)-1] = '\0';
2142  psSHP->sHooks.Error( szErrorMsg );
2144  return SHPLIB_NULLPTR;
2145  }
2146 
2147  if( psShape->bFastModeReadObject )
2148  {
2149  int nObjectBufSize = 4 * sizeof(double) * nPoints + 2 * sizeof(int) * nParts;
2150  pBuffer = SHPReallocObjectBufIfNecessary(psSHP, nObjectBufSize);
2151  ppBuffer = &pBuffer;
2152  }
2153 
2154  psShape->nVertices = nPoints;
2155  psShape->padfX = STATIC_CAST(double *, SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints));
2156  psShape->padfY = STATIC_CAST(double *, SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints));
2157  psShape->padfZ = STATIC_CAST(double *, SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints));
2158  psShape->padfM = STATIC_CAST(double *, SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints));
2159 
2160  psShape->nParts = nParts;
2161  psShape->panPartStart = STATIC_CAST(int *, SHPAllocBuffer(ppBuffer, nParts * sizeof(int)));
2162  psShape->panPartType = STATIC_CAST(int *, SHPAllocBuffer(ppBuffer, nParts * sizeof(int)));
2163 
2164  if (psShape->padfX == SHPLIB_NULLPTR ||
2165  psShape->padfY == SHPLIB_NULLPTR ||
2166  psShape->padfZ == SHPLIB_NULLPTR ||
2167  psShape->padfM == SHPLIB_NULLPTR ||
2168  psShape->panPartStart == SHPLIB_NULLPTR ||
2169  psShape->panPartType == SHPLIB_NULLPTR)
2170  {
2171  snprintf(szErrorMsg, sizeof(szErrorMsg),
2172  "Not enough memory to allocate requested memory (nPoints=%u, nParts=%u) for shape %d. "
2173  "Probably broken SHP file", nPoints, nParts, hEntity );
2174  szErrorMsg[sizeof(szErrorMsg)-1] = '\0';
2175  psSHP->sHooks.Error( szErrorMsg );
2177  return SHPLIB_NULLPTR;
2178  }
2179 
2180  for( i = 0; STATIC_CAST(int32, i) < nParts; i++ )
2181  psShape->panPartType[i] = SHPP_RING;
2182 
2183 /* -------------------------------------------------------------------- */
2184 /* Copy out the part array from the record. */
2185 /* -------------------------------------------------------------------- */
2186  memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts );
2187  for( i = 0; STATIC_CAST(int32, i) < nParts; i++ )
2188  {
2189  if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i );
2190 
2191  /* We check that the offset is inside the vertex array */
2192  if (psShape->panPartStart[i] < 0
2193  || (psShape->panPartStart[i] >= psShape->nVertices
2194  && psShape->nVertices > 0)
2195  || (psShape->panPartStart[i] > 0 && psShape->nVertices == 0) )
2196  {
2197  snprintf(szErrorMsg, sizeof(szErrorMsg),
2198  "Corrupted .shp file : shape %d : panPartStart[%d] = %d, nVertices = %d",
2199  hEntity, i, psShape->panPartStart[i], psShape->nVertices);
2200  szErrorMsg[sizeof(szErrorMsg)-1] = '\0';
2201  psSHP->sHooks.Error( szErrorMsg );
2203  return SHPLIB_NULLPTR;
2204  }
2205  if (i > 0 && psShape->panPartStart[i] <= psShape->panPartStart[i-1])
2206  {
2207  snprintf(szErrorMsg, sizeof(szErrorMsg),
2208  "Corrupted .shp file : shape %d : panPartStart[%d] = %d, panPartStart[%d] = %d",
2209  hEntity, i, psShape->panPartStart[i], i - 1, psShape->panPartStart[i - 1]);
2210  szErrorMsg[sizeof(szErrorMsg)-1] = '\0';
2211  psSHP->sHooks.Error( szErrorMsg );
2213  return SHPLIB_NULLPTR;
2214  }
2215  }
2216 
2217  nOffset = 44 + 8 + 4*nParts;
2218 
2219 /* -------------------------------------------------------------------- */
2220 /* If this is a multipatch, we will also have parts types. */
2221 /* -------------------------------------------------------------------- */
2222  if( psShape->nSHPType == SHPT_MULTIPATCH )
2223  {
2224  memcpy( psShape->panPartType, psSHP->pabyRec + nOffset, 4*nParts );
2225  for( i = 0; STATIC_CAST(int32, i) < nParts; i++ )
2226  {
2227  if( bBigEndian ) SwapWord( 4, psShape->panPartType+i );
2228  }
2229 
2230  nOffset += 4*nParts;
2231  }
2232 
2233 /* -------------------------------------------------------------------- */
2234 /* Copy out the vertices from the record. */
2235 /* -------------------------------------------------------------------- */
2236  for( i = 0; STATIC_CAST(int32, i) < nPoints; i++ )
2237  {
2238  memcpy(psShape->padfX + i,
2239  psSHP->pabyRec + nOffset + i * 16,
2240  8 );
2241 
2242  memcpy(psShape->padfY + i,
2243  psSHP->pabyRec + nOffset + i * 16 + 8,
2244  8 );
2245 
2246  if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
2247  if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
2248  }
2249 
2250  nOffset += 16*nPoints;
2251 
2252 /* -------------------------------------------------------------------- */
2253 /* If we have a Z coordinate, collect that now. */
2254 /* -------------------------------------------------------------------- */
2255  if( psShape->nSHPType == SHPT_POLYGONZ
2256  || psShape->nSHPType == SHPT_ARCZ
2257  || psShape->nSHPType == SHPT_MULTIPATCH )
2258  {
2259  memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 );
2260  memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
2261 
2262  if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) );
2263  if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) );
2264 
2265  for( i = 0; STATIC_CAST(int32, i) < nPoints; i++ )
2266  {
2267  memcpy( psShape->padfZ + i,
2268  psSHP->pabyRec + nOffset + 16 + i*8, 8 );
2269  if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );
2270  }
2271 
2272  nOffset += 16 + 8*nPoints;
2273  }
2274  else if( psShape->bFastModeReadObject )
2275  {
2276  psShape->padfZ = SHPLIB_NULLPTR;
2277  }
2278 
2279 /* -------------------------------------------------------------------- */
2280 /* If we have a M measure value, then read it now. We assume */
2281 /* that the measure can be present for any shape if the size is */
2282 /* big enough, but really it will only occur for the Z shapes */
2283 /* (options), and the M shapes. */
2284 /* -------------------------------------------------------------------- */
2285  if( nEntitySize >= STATIC_CAST(int, nOffset + 16 + 8*nPoints) )
2286  {
2287  memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
2288  memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
2289 
2290  if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) );
2291  if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) );
2292 
2293  for( i = 0; STATIC_CAST(int32, i) < nPoints; i++ )
2294  {
2295  memcpy( psShape->padfM + i,
2296  psSHP->pabyRec + nOffset + 16 + i*8, 8 );
2297  if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
2298  }
2299  psShape->bMeasureIsUsed = TRUE;
2300  }
2301  else if( psShape->bFastModeReadObject )
2302  {
2303  psShape->padfM = SHPLIB_NULLPTR;
2304  }
2305  }
#define SHPT_ARCZ
Definition: shapefil.h:354
#define SHPT_MULTIPATCH
Definition: shapefil.h:361
#define SHPP_RING
Definition: shapefil.h:373
#define SHPT_POLYGONZ
Definition: shapefil.h:355
static unsigned char * SHPReallocObjectBufIfNecessary(SHPHandle psSHP, int nObjectBufSize)
Definition: shpopen.c:1801
static int bBigEndian
Definition: shpopen.c:93
unsigned int int32
Definition: shpopen.c:54
else psShape
Definition: shpopen.c:2055
nEntitySize
Definition: shpopen.c:1897
static void SwapWord(int length, void *wordP)
Definition: shpopen.c:110
#define STATIC_CAST(type, x)
Definition: shpopen.c:100
#define TRUE
Definition: shpopen.c:59
void SHPAPI_CALL SHPDestroyObject(SHPObject *psShape)
Definition: shpopen.c:2641
static void * SHPAllocBuffer(unsigned char **pBuffer, int nSize)
Definition: shpopen.c:1782
#define SHPLIB_NULLPTR
Definition: shpopen.c:101

References bBigEndian, nEntitySize, psShape, SHPAllocBuffer(), SHPDestroyObject(), SHPLIB_NULLPTR, SHPP_RING, SHPReallocObjectBufIfNecessary(), SHPT_ARCZ, SHPT_MULTIPATCH, SHPT_POLYGONZ, STATIC_CAST, SwapWord(), and TRUE.

Here is the call graph for this function: