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

◆ 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 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
static unsigned char * SHPReallocObjectBufIfNecessary(SHPHandle psSHP, int nObjectBufSize)
Definition shpopen.c:1801
#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
#define SHPLIB_NULLPTR
Definition shpopen.c:101
static void * SHPAllocBuffer(unsigned char **pBuffer, int nSize)
Definition shpopen.c:1782

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: