PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ if() [8/10]

Definition at line 2075 of file shpopen.c.

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

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: