OGRErr OGRCurveCollection::importBodyFromWkb( OGRGeometry* poGeom, unsigned char * pabyData, int nSize, int nDataOffset, int bAcceptCompoundCurve, OGRErr (*pfnAddCurveDirectlyFromWkb)(OGRGeometry* poGeom, OGRCurve* poCurve), OGRwkbVariant eWkbVariant ) { /* -------------------------------------------------------------------- */ /* Get the Geoms. */ /* -------------------------------------------------------------------- */ int nIter = nCurveCount; nCurveCount = 0; for( int iGeom = 0; iGeom < nIter; iGeom++ ) { OGRErr eErr; OGRGeometry* poSubGeom = NULL; /* Parses sub-geometry */ unsigned char* pabySubData = pabyData + nDataOffset; if( nSize < 9 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; OGRwkbGeometryType eSubGeomType; OGRBoolean bIs3D; if ( OGRReadWKBGeometryType( pabySubData, eWkbVariant, &eSubGeomType, &bIs3D ) != OGRERR_NONE ) return OGRERR_FAILURE; if( (eSubGeomType != wkbCompoundCurve && OGR_GT_IsCurve(eSubGeomType)) || (bAcceptCompoundCurve && eSubGeomType == wkbCompoundCurve) ) { eErr = OGRGeometryFactory:: createFromWkb( pabySubData, NULL, &poSubGeom, nSize, eWkbVariant ); } else { CPLDebug("OGR", "Cannot add geometry of type (%d) to geometry of type (%d)", eSubGeomType, poGeom->getGeometryType()); return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; } if( eErr == OGRERR_NONE ) eErr = pfnAddCurveDirectlyFromWkb(poGeom, (OGRCurve*)poSubGeom); if( eErr != OGRERR_NONE ) { delete poSubGeom; return eErr; } int nSubGeomWkbSize = poSubGeom->WkbSize(); if( nSize != -1 ) nSize -= nSubGeomWkbSize; nDataOffset += nSubGeomWkbSize; } return OGRERR_NONE; }
OGRErr OGRPoint::importFromWkb( unsigned char * pabyData, int nSize ) { OGRwkbByteOrder eByteOrder; if( nSize < 21 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the byte order byte. */ /* -------------------------------------------------------------------- */ eByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabyData); if (!( eByteOrder == wkbXDR || eByteOrder == wkbNDR )) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Get the geometry feature type. For now we assume that */ /* geometry type is between 0 and 255 so we only have to fetch */ /* one byte. */ /* -------------------------------------------------------------------- */ OGRBoolean bIs3D; OGRwkbGeometryType eGeometryType; OGRErr err = OGRReadWKBGeometryType( pabyData, &eGeometryType, &bIs3D ); if( err != OGRERR_NONE || eGeometryType != wkbPoint ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Get the vertex. */ /* -------------------------------------------------------------------- */ memcpy( &x, pabyData + 5, 8 ); memcpy( &y, pabyData + 5 + 8, 8 ); if( OGR_SWAP( eByteOrder ) ) { CPL_SWAPDOUBLE( &x ); CPL_SWAPDOUBLE( &y ); } if( bIs3D ) { if ( nSize < 29 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; memcpy( &z, pabyData + 5 + 16, 8 ); if( OGR_SWAP( eByteOrder ) ) { CPL_SWAPDOUBLE( &z ); } nCoordDimension = 3; } else { z = 0; nCoordDimension = 2; } return OGRERR_NONE; }
OGRErr OGRGeometryCollection::importFromWkbInternal( const unsigned char * pabyData, int nSize, int nRecLevel, OGRwkbVariant eWkbVariant, int& nBytesConsumedOut ) { nBytesConsumedOut = -1; // Arbitrary value, but certainly large enough for reasonable use cases. if( nRecLevel == 32 ) { CPLError( CE_Failure, CPLE_AppDefined, "Too many recursion levels (%d) while parsing WKB geometry.", nRecLevel ); return OGRERR_CORRUPT_DATA; } nGeomCount = 0; OGRwkbByteOrder eByteOrder = wkbXDR; int nDataOffset = 0; OGRErr eErr = importPreambleOfCollectionFromWkb( pabyData, nSize, nDataOffset, eByteOrder, 9, nGeomCount, eWkbVariant ); if( eErr != OGRERR_NONE ) return eErr; // coverity[tainted_data] papoGeoms = static_cast<OGRGeometry **>( VSI_CALLOC_VERBOSE(sizeof(void*), nGeomCount)); if( nGeomCount != 0 && papoGeoms == nullptr ) { nGeomCount = 0; return OGRERR_NOT_ENOUGH_MEMORY; } /* -------------------------------------------------------------------- */ /* Get the Geoms. */ /* -------------------------------------------------------------------- */ for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { // Parses sub-geometry. const unsigned char* pabySubData = pabyData + nDataOffset; if( nSize < 9 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; OGRwkbGeometryType eSubGeomType = wkbUnknown; eErr = OGRReadWKBGeometryType( pabySubData, eWkbVariant, &eSubGeomType ); if( eErr != OGRERR_NONE ) return eErr; if( !isCompatibleSubType(eSubGeomType) ) { nGeomCount = iGeom; CPLDebug( "OGR", "Cannot add geometry of type (%d) to geometry of type (%d)", eSubGeomType, getGeometryType()); return OGRERR_CORRUPT_DATA; } OGRGeometry* poSubGeom = nullptr; int nSubGeomBytesConsumed = -1; if( OGR_GT_IsSubClassOf(eSubGeomType, wkbGeometryCollection) ) { poSubGeom = OGRGeometryFactory::createGeometry( eSubGeomType ); if( poSubGeom == nullptr ) eErr = OGRERR_FAILURE; else eErr = poSubGeom->toGeometryCollection()-> importFromWkbInternal( pabySubData, nSize, nRecLevel + 1, eWkbVariant, nSubGeomBytesConsumed ); } else { eErr = OGRGeometryFactory:: createFromWkb( pabySubData, nullptr, &poSubGeom, nSize, eWkbVariant, nSubGeomBytesConsumed ); } if( eErr != OGRERR_NONE ) { nGeomCount = iGeom; delete poSubGeom; return eErr; } papoGeoms[iGeom] = poSubGeom; if( papoGeoms[iGeom]->Is3D() ) flags |= OGR_G_3D; if( papoGeoms[iGeom]->IsMeasured() ) flags |= OGR_G_MEASURED; CPLAssert( nSubGeomBytesConsumed > 0 ); if( nSize != -1 ) { CPLAssert( nSize >= nSubGeomBytesConsumed ); nSize -= nSubGeomBytesConsumed; } nDataOffset += nSubGeomBytesConsumed; } nBytesConsumedOut = nDataOffset; return OGRERR_NONE; }