PostGIS  3.1.6dev-r@@SVN_REVISION@@

◆ if() [8/10]

Definition at line 2066 of file shpopen.c.

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