static OGRGeometryCollection* LoadGeometry( const char* pszDS, const char* pszSQL, const char* pszLyr, const char* pszWhere ) { GDALDataset *poDS; OGRLayer *poLyr; OGRFeature *poFeat; OGRGeometryCollection *poGeom = NULL; poDS = (GDALDataset*) GDALOpen( pszDS, GA_ReadOnly ); if ( poDS == NULL ) return NULL; if ( pszSQL != NULL ) poLyr = poDS->ExecuteSQL( pszSQL, NULL, NULL ); else if ( pszLyr != NULL ) poLyr = poDS->GetLayerByName( pszLyr ); else poLyr = poDS->GetLayer(0); if ( poLyr == NULL ) { fprintf( stderr, "FAILURE: Failed to identify source layer from datasource.\n" ); GDALClose( (GDALDatasetH) poDS ); return NULL; } if ( pszWhere ) poLyr->SetAttributeFilter( pszWhere ); while ( (poFeat = poLyr->GetNextFeature()) != NULL ) { OGRGeometry* poSrcGeom = poFeat->GetGeometryRef(); if ( poSrcGeom ) { OGRwkbGeometryType eType = wkbFlatten( poSrcGeom->getGeometryType() ); if ( poGeom == NULL ) poGeom = new OGRMultiPolygon(); if ( eType == wkbPolygon ) poGeom->addGeometry( poSrcGeom ); else if ( eType == wkbMultiPolygon ) { int iGeom; int nGeomCount = ((OGRMultiPolygon *)poSrcGeom)->getNumGeometries(); for ( iGeom = 0; iGeom < nGeomCount; iGeom++ ) { poGeom->addGeometry( ((OGRMultiPolygon *)poSrcGeom)->getGeometryRef(iGeom) ); } } else { fprintf( stderr, "FAILURE: Geometry not of polygon type.\n" ); OGRGeometryFactory::destroyGeometry( poGeom ); OGRFeature::DestroyFeature( poFeat ); if ( pszSQL != NULL ) poDS->ReleaseResultSet( poLyr ); GDALClose( (GDALDatasetH) poDS ); return NULL; } } OGRFeature::DestroyFeature( poFeat ); } if( pszSQL != NULL ) poDS->ReleaseResultSet( poLyr ); GDALClose( (GDALDatasetH) poDS ); return poGeom; }
MAIN_START(nArgc, papszArgv) { // Check strict compilation and runtime library version as we use C++ API. if( !GDAL_CHECK_VERSION(papszArgv[0]) ) exit(1); EarlySetConfigOptions(nArgc, papszArgv); OGRRegisterAll(); /* -------------------------------------------------------------------- */ /* Processing command line arguments. */ /* -------------------------------------------------------------------- */ nArgc = OGRGeneralCmdLineProcessor(nArgc, &papszArgv, 0); if( nArgc < 1 ) exit(-nArgc); char *pszWHERE = nullptr; const char *pszDataSource = nullptr; char **papszLayers = nullptr; OGRGeometry *poSpatialFilter = nullptr; int nRepeatCount = 1; bool bAllLayers = false; char *pszSQLStatement = nullptr; const char *pszDialect = nullptr; int nRet = 0; const char* pszGeomField = nullptr; char **papszOpenOptions = nullptr; char **papszExtraMDDomains = nullptr; bool bListMDD = false; bool bShowMetadata = true; bool bFeatureCount = true; bool bExtent = true; bool bDatasetGetNextFeature = false; bool bReadOnly = false; bool bUpdate = false; const char* pszWKTFormat = "WKT2"; for( int iArg = 1; iArg < nArgc; iArg++ ) { if( EQUAL(papszArgv[iArg], "--utility_version") ) { printf("%s was compiled against GDAL %s and " "is running against GDAL %s\n", papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); CSLDestroy(papszArgv); return 0; } else if( EQUAL(papszArgv[iArg], "--help") ) { Usage(); } else if( EQUAL(papszArgv[iArg], "-ro") ) { bReadOnly = true; } else if( EQUAL(papszArgv[iArg], "-update") ) { bUpdate = true; } else if( EQUAL(papszArgv[iArg], "-q") || EQUAL(papszArgv[iArg], "-quiet")) { bVerbose = false; } else if( EQUAL(papszArgv[iArg], "-qq") ) { /* Undocumented: mainly only useful for AFL testing */ bVerbose = false; bSuperQuiet = true; } else if( EQUAL(papszArgv[iArg], "-fid") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); nFetchFID = CPLAtoGIntBig(papszArgv[++iArg]); } else if( EQUAL(papszArgv[iArg], "-spat") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(4); OGRLinearRing oRing; oRing.addPoint(CPLAtof(papszArgv[iArg+1]), CPLAtof(papszArgv[iArg+2])); oRing.addPoint(CPLAtof(papszArgv[iArg+1]), CPLAtof(papszArgv[iArg+4])); oRing.addPoint(CPLAtof(papszArgv[iArg+3]), CPLAtof(papszArgv[iArg+4])); oRing.addPoint(CPLAtof(papszArgv[iArg+3]), CPLAtof(papszArgv[iArg+2])); oRing.addPoint(CPLAtof(papszArgv[iArg+1]), CPLAtof(papszArgv[iArg+2])); poSpatialFilter = new OGRPolygon(); static_cast<OGRPolygon *>(poSpatialFilter)->addRing(&oRing); iArg += 4; } else if( EQUAL(papszArgv[iArg], "-geomfield") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszGeomField = papszArgv[++iArg]; } else if( EQUAL(papszArgv[iArg], "-where") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); iArg++; CPLFree(pszWHERE); GByte* pabyRet = nullptr; if( papszArgv[iArg][0] == '@' && VSIIngestFile(nullptr, papszArgv[iArg] + 1, &pabyRet, nullptr, 1024*1024) ) { RemoveBOM(pabyRet); pszWHERE = reinterpret_cast<char *>(pabyRet); } else { pszWHERE = CPLStrdup(papszArgv[iArg]); } } else if( EQUAL(papszArgv[iArg], "-sql") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); iArg++; CPLFree(pszSQLStatement); GByte* pabyRet = nullptr; if( papszArgv[iArg][0] == '@' && VSIIngestFile(nullptr, papszArgv[iArg] + 1, &pabyRet, nullptr, 1024*1024) ) { RemoveBOM(pabyRet); pszSQLStatement = reinterpret_cast<char *>(pabyRet); RemoveSQLComments(pszSQLStatement); } else { pszSQLStatement = CPLStrdup(papszArgv[iArg]); } } else if( EQUAL(papszArgv[iArg], "-dialect") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszDialect = papszArgv[++iArg]; } else if( EQUAL(papszArgv[iArg], "-rc") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); nRepeatCount = atoi(papszArgv[++iArg]); } else if( EQUAL(papszArgv[iArg], "-al") ) { bAllLayers = true; } else if( EQUAL(papszArgv[iArg], "-so") || EQUAL(papszArgv[iArg], "-summary") ) { bSummaryOnly = true; } else if( STARTS_WITH_CI(papszArgv[iArg], "-fields=") ) { char* pszTemp = static_cast<char *>(CPLMalloc(32 + strlen(papszArgv[iArg]))); snprintf(pszTemp, 32 + strlen(papszArgv[iArg]), "DISPLAY_FIELDS=%s", papszArgv[iArg] + strlen("-fields=")); papszOptions = CSLAddString(papszOptions, pszTemp); CPLFree(pszTemp); } else if( STARTS_WITH_CI(papszArgv[iArg], "-geom=") ) { char* pszTemp = static_cast<char *>(CPLMalloc(32 + strlen(papszArgv[iArg]))); snprintf(pszTemp, 32 + strlen(papszArgv[iArg]), "DISPLAY_GEOMETRY=%s", papszArgv[iArg] + strlen("-geom=")); papszOptions = CSLAddString(papszOptions, pszTemp); CPLFree(pszTemp); } else if( EQUAL(papszArgv[iArg], "-oo") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); papszOpenOptions = CSLAddString(papszOpenOptions, papszArgv[++iArg]); } else if( EQUAL(papszArgv[iArg], "-nomd") ) { bShowMetadata = false; } else if( EQUAL(papszArgv[iArg], "-listmdd") ) { bListMDD = true; } else if( EQUAL(papszArgv[iArg], "-mdd") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); papszExtraMDDomains = CSLAddString(papszExtraMDDomains, papszArgv[++iArg]); } else if( EQUAL(papszArgv[iArg], "-nocount") ) { bFeatureCount = false; } else if( EQUAL(papszArgv[iArg], "-noextent") ) { bExtent = false; } else if( EQUAL(papszArgv[iArg], "-rl")) { bDatasetGetNextFeature = true; } else if( EQUAL(papszArgv[iArg], "-wkt_format") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszWKTFormat = papszArgv[++iArg]; } else if( papszArgv[iArg][0] == '-' ) { Usage(CPLSPrintf("Unknown option name '%s'", papszArgv[iArg])); } else if( pszDataSource == nullptr ) { pszDataSource = papszArgv[iArg]; } else { papszLayers = CSLAddString(papszLayers, papszArgv[iArg]); bAllLayers = false; } } if( pszDataSource == nullptr ) Usage("No datasource specified."); if( pszDialect != nullptr && pszWHERE != nullptr && pszSQLStatement == nullptr ) printf("Warning: -dialect is ignored with -where. Use -sql instead"); if( bDatasetGetNextFeature && pszSQLStatement ) { Usage("-rl is incompatible with -sql"); } #ifdef __AFL_HAVE_MANUAL_CONTROL while (__AFL_LOOP(1000)) { #endif /* -------------------------------------------------------------------- */ /* Open data source. */ /* -------------------------------------------------------------------- */ GDALDataset *poDS = static_cast<GDALDataset *>(GDALOpenEx( pszDataSource, ((bReadOnly || pszSQLStatement == nullptr) && !bUpdate ? GDAL_OF_READONLY : GDAL_OF_UPDATE) | GDAL_OF_VECTOR, nullptr, papszOpenOptions, nullptr)); if( poDS == nullptr && !bReadOnly && !bUpdate && pszSQLStatement == nullptr ) { // In some cases (empty geopackage for example), opening in read-only // mode fails, so retry in update mode if( GDALIdentifyDriverEx(pszDataSource, GDAL_OF_VECTOR, nullptr, nullptr) ) { poDS = static_cast<GDALDataset *>(GDALOpenEx( pszDataSource, GDAL_OF_UPDATE | GDAL_OF_VECTOR, nullptr, papszOpenOptions, nullptr)); } } if( poDS == nullptr && !bReadOnly && !bUpdate && pszSQLStatement != nullptr ) { poDS = static_cast<GDALDataset *>(GDALOpenEx( pszDataSource, GDAL_OF_READONLY | GDAL_OF_VECTOR, nullptr, papszOpenOptions, nullptr)); if( poDS != nullptr && bVerbose ) { printf("Had to open data source read-only.\n"); #ifdef __AFL_HAVE_MANUAL_CONTROL bReadOnly = true; #endif } } GDALDriver *poDriver = nullptr; if( poDS != nullptr ) poDriver = poDS->GetDriver(); /* -------------------------------------------------------------------- */ /* Report failure */ /* -------------------------------------------------------------------- */ if( poDS == nullptr ) { printf("FAILURE:\n" "Unable to open datasource `%s' with the following drivers.\n", pszDataSource); #ifdef __AFL_HAVE_MANUAL_CONTROL continue; #else OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar(); for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ ) { printf(" -> %s\n", poR->GetDriver(iDriver)->GetDescription()); } nRet = 1; goto end; #endif } CPLAssert(poDriver != nullptr); /* -------------------------------------------------------------------- */ /* Some information messages. */ /* -------------------------------------------------------------------- */ if( bVerbose ) printf("INFO: Open of `%s'\n" " using driver `%s' successful.\n", pszDataSource, poDriver->GetDescription()); if( bVerbose && !EQUAL(pszDataSource,poDS->GetDescription()) ) { printf("INFO: Internal data source name `%s'\n" " different from user name `%s'.\n", poDS->GetDescription(), pszDataSource); } GDALInfoReportMetadata(static_cast<GDALMajorObjectH>(poDS), bListMDD, bShowMetadata, papszExtraMDDomains); if( bDatasetGetNextFeature ) { nRepeatCount = 0; // skip layer reporting. /* -------------------------------------------------------------------- */ /* Set filters if provided. */ /* -------------------------------------------------------------------- */ if( pszWHERE != nullptr || poSpatialFilter != nullptr ) { for( int iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ ) { OGRLayer *poLayer = poDS->GetLayer(iLayer); if( poLayer == nullptr ) { printf("FAILURE: Couldn't fetch advertised layer %d!\n", iLayer); exit(1); } if( pszWHERE != nullptr ) { if( poLayer->SetAttributeFilter(pszWHERE) != OGRERR_NONE ) { printf("WARNING: SetAttributeFilter(%s) " "failed on layer %s.\n", pszWHERE, poLayer->GetName()); } } if( poSpatialFilter != nullptr ) { if( pszGeomField != nullptr ) { OGRFeatureDefn *poDefn = poLayer->GetLayerDefn(); const int iGeomField = poDefn->GetGeomFieldIndex(pszGeomField); if( iGeomField >= 0 ) poLayer->SetSpatialFilter(iGeomField, poSpatialFilter); else printf("WARNING: Cannot find geometry field %s.\n", pszGeomField); } else { poLayer->SetSpatialFilter(poSpatialFilter); } } } } std::set<OGRLayer*> oSetLayers; while( true ) { OGRLayer* poLayer = nullptr; OGRFeature* poFeature = poDS->GetNextFeature(&poLayer, nullptr, nullptr, nullptr); if( poFeature == nullptr ) break; if( papszLayers == nullptr || poLayer == nullptr || CSLFindString(papszLayers, poLayer->GetName()) >= 0 ) { if( bVerbose && poLayer != nullptr && oSetLayers.find(poLayer) == oSetLayers.end() ) { oSetLayers.insert(poLayer); const bool bSummaryOnlyBackup = bSummaryOnly; bSummaryOnly = true; ReportOnLayer(poLayer, nullptr, nullptr, nullptr, bListMDD, bShowMetadata, papszExtraMDDomains, bFeatureCount, bExtent, pszWKTFormat); bSummaryOnly = bSummaryOnlyBackup; } if( !bSuperQuiet && !bSummaryOnly ) poFeature->DumpReadable(nullptr, papszOptions); } OGRFeature::DestroyFeature(poFeature); } } /* -------------------------------------------------------------------- */ /* Special case for -sql clause. No source layers required. */ /* -------------------------------------------------------------------- */ else if( pszSQLStatement != nullptr ) { nRepeatCount = 0; // skip layer reporting. if( CSLCount(papszLayers) > 0 ) printf("layer names ignored in combination with -sql.\n"); OGRLayer *poResultSet = poDS->ExecuteSQL( pszSQLStatement, pszGeomField == nullptr ? poSpatialFilter : nullptr, pszDialect); if( poResultSet != nullptr ) { if( pszWHERE != nullptr ) { if( poResultSet->SetAttributeFilter(pszWHERE) != OGRERR_NONE ) { printf("FAILURE: SetAttributeFilter(%s) failed.\n", pszWHERE); exit(1); } } if( pszGeomField != nullptr ) ReportOnLayer(poResultSet, nullptr, pszGeomField, poSpatialFilter, bListMDD, bShowMetadata, papszExtraMDDomains, bFeatureCount, bExtent, pszWKTFormat); else ReportOnLayer(poResultSet, nullptr, nullptr, nullptr, bListMDD, bShowMetadata, papszExtraMDDomains, bFeatureCount, bExtent, pszWKTFormat); poDS->ReleaseResultSet(poResultSet); } } // coverity[tainted_data] for( int iRepeat = 0; iRepeat < nRepeatCount; iRepeat++ ) { if( papszLayers == nullptr || *papszLayers == nullptr ) { if( iRepeat == 0 ) CPLDebug("OGR", "GetLayerCount() = %d\n", poDS->GetLayerCount()); /* -------------------------------------------------------------------- */ /* Process each data source layer. */ /* -------------------------------------------------------------------- */ for( int iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ ) { OGRLayer *poLayer = poDS->GetLayer(iLayer); if( poLayer == nullptr ) { printf("FAILURE: Couldn't fetch advertised layer %d!\n", iLayer); exit(1); } if( !bAllLayers ) { printf("%d: %s", iLayer + 1, poLayer->GetName()); const int nGeomFieldCount = poLayer->GetLayerDefn()->GetGeomFieldCount(); if( nGeomFieldCount > 1 ) { printf(" ("); for( int iGeom = 0; iGeom < nGeomFieldCount; iGeom++ ) { if( iGeom > 0 ) printf(", "); OGRGeomFieldDefn* poGFldDefn = poLayer->GetLayerDefn()-> GetGeomFieldDefn(iGeom); printf( "%s", OGRGeometryTypeToName( poGFldDefn->GetType())); } printf(")"); } else if( poLayer->GetGeomType() != wkbUnknown ) printf(" (%s)", OGRGeometryTypeToName( poLayer->GetGeomType())); printf("\n"); } else { if( iRepeat != 0 ) poLayer->ResetReading(); ReportOnLayer(poLayer, pszWHERE, pszGeomField, poSpatialFilter, bListMDD, bShowMetadata, papszExtraMDDomains, bFeatureCount, bExtent, pszWKTFormat); } } } else { /* -------------------------------------------------------------------- */ /* Process specified data source layers. */ /* -------------------------------------------------------------------- */ for( char** papszIter = papszLayers; *papszIter != nullptr; ++papszIter ) { OGRLayer *poLayer = poDS->GetLayerByName(*papszIter); if( poLayer == nullptr ) { printf("FAILURE: Couldn't fetch requested layer %s!\n", *papszIter); exit(1); } if( iRepeat != 0 ) poLayer->ResetReading(); ReportOnLayer(poLayer, pszWHERE, pszGeomField, poSpatialFilter, bListMDD, bShowMetadata, papszExtraMDDomains, bFeatureCount, bExtent, pszWKTFormat); } } } /* -------------------------------------------------------------------- */ /* Close down. */ /* -------------------------------------------------------------------- */ GDALClose(poDS); #ifdef __AFL_HAVE_MANUAL_CONTROL } #else end: #endif CSLDestroy(papszArgv); CSLDestroy(papszLayers); CSLDestroy(papszOptions); CSLDestroy(papszOpenOptions); CSLDestroy(papszExtraMDDomains); if( poSpatialFilter ) OGRGeometryFactory::destroyGeometry(poSpatialFilter); CPLFree(pszSQLStatement); CPLFree(pszWHERE); OGRCleanupAll(); return nRet; }