int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
{
    VSILFILE* fp = VSIFileFromMemBuffer( "/vsimem/test.tar",
            reinterpret_cast<GByte*>(const_cast<uint8_t*>(buf)), len, FALSE );
    VSIFCloseL(fp);

    CPLPushErrorHandler(CPLQuietErrorHandler);

    char** papszArgv = nullptr;

    CPLString osOutFilename("out");
    fp = VSIFOpenL("/vsitar//vsimem/test.tar/cmd.txt", "rb");
    if( fp != nullptr )
    {
        const char* pszLine = nullptr;
        if( (pszLine = CPLReadLineL(fp)) != nullptr )
        {
            osOutFilename = pszLine;
            osOutFilename = osOutFilename.replaceAll('/', '_');
        }
        int nCandidateLayerNames = 0;
        while( (pszLine = CPLReadLineL(fp)) != nullptr )
        {
            if( pszLine[0] != '-' )
            {
                nCandidateLayerNames ++;
                if( nCandidateLayerNames == 10 )
                    break;
            }
            papszArgv = CSLAddString(papszArgv, pszLine);
        }
        VSIFCloseL(fp);
    }

    char** papszDrivers = CSLAddString(nullptr, "CSV");
    GDALDatasetH hSrcDS = GDALOpenEx( "/vsitar//vsimem/test.tar/in",
                        GDAL_OF_VECTOR, papszDrivers, nullptr, nullptr );
    CSLDestroy(papszDrivers);

    if( papszArgv != nullptr && hSrcDS != nullptr )
    {
        OGRLayerH hLayer = GDALDatasetGetLayer(hSrcDS, 0);
        if( hLayer )
        {
            int nFieldCount = OGR_FD_GetFieldCount(
                OGR_L_GetLayerDefn(hLayer));
            if( nFieldCount > 100 )
            {
                papszArgv = CSLAddString(papszArgv, "-limit");
                papszArgv = CSLAddString(papszArgv, "100");
            }
        }

        GDALVectorTranslateOptions* psOptions =
            GDALVectorTranslateOptionsNew(papszArgv, nullptr);
        if( psOptions )
        {
            CPLString osFullOutFilename("/vsimem/" + osOutFilename);
            GDALDatasetH hOutDS = GDALVectorTranslate(
                osFullOutFilename.c_str(),
                nullptr, 1, &hSrcDS, psOptions, nullptr);
            if( hOutDS )
            {
                GDALDriverH hOutDrv = GDALGetDatasetDriver(hOutDS);
                GDALClose(hOutDS);

                // Try re-opening generated file
                GDALClose(
                    GDALOpenEx(osFullOutFilename, GDAL_OF_VECTOR,
                            nullptr, nullptr, nullptr));

                if( hOutDrv )
                    GDALDeleteDataset(hOutDrv, osFullOutFilename);
            }
            GDALVectorTranslateOptionsFree(psOptions);
        }
    }
    CSLDestroy(papszArgv);
    GDALClose(hSrcDS);

    VSIRmdirRecursive("/vsimem/");

    CPLPopErrorHandler();

    return 0;
}
Exemple #2
0
int main( int nArgc, char ** papszArgv )
{
    GDALDatasetH hDS = NULL;
    GDALDatasetH hODS = NULL;
    int bCloseODS = TRUE;
    int bUsageError = FALSE;
    GDALDatasetH hDstDS;
    int nRetCode = 1;
    GDALVectorTranslateOptionsForBinary* psOptionsForBinary;
    GDALVectorTranslateOptions *psOptions;

    /* Check strict compilation and runtime library version as we use C++ API */
    if (! GDAL_CHECK_VERSION(papszArgv[0]))
        exit(1);

    EarlySetConfigOptions(nArgc, papszArgv);

/* -------------------------------------------------------------------- */
/*      Register format(s).                                             */
/* -------------------------------------------------------------------- */
    OGRRegisterAll();

/* -------------------------------------------------------------------- */
/*      Processing command line arguments.                              */
/* -------------------------------------------------------------------- */
    nArgc = OGRGeneralCmdLineProcessor( nArgc, &papszArgv, 0 );

    if( nArgc < 1 )
    {
        papszArgv = NULL;
        nRetCode = -nArgc;
        goto exit;
    }

    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"));
            nRetCode = 0;
            goto exit;
        }
        else if( EQUAL(papszArgv[iArg],"--help") )
        {
            Usage();
            goto exit;
        }
        else if ( EQUAL(papszArgv[iArg], "--long-usage") )
        {
            Usage(FALSE);
            goto exit;
        }
    }

    psOptionsForBinary = GDALVectorTranslateOptionsForBinaryNew();
    psOptions = GDALVectorTranslateOptionsNew(papszArgv + 1, psOptionsForBinary);

    if( psOptions == NULL )
    {
        Usage();
        GDALVectorTranslateOptionsForBinaryFree(psOptionsForBinary);
        goto exit;
    }

    if( psOptionsForBinary->pszDataSource == NULL ||
        psOptionsForBinary->pszDestDataSource == NULL )
    {
        if( psOptionsForBinary->pszDestDataSource == NULL )
            Usage("no target datasource provided");
        else
            Usage("no source datasource provided");
        GDALVectorTranslateOptionsFree(psOptions);
        GDALVectorTranslateOptionsForBinaryFree(psOptionsForBinary);
        goto exit;
    }

    if( strcmp(psOptionsForBinary->pszDestDataSource, "/vsistdout/") == 0 )
        psOptionsForBinary->bQuiet = TRUE;

    if (!psOptionsForBinary->bQuiet && !psOptionsForBinary->bFormatExplicitlySet &&
        psOptionsForBinary->eAccessMode == ACCESS_CREATION)
    {
        CheckDestDataSourceNameConsistency(psOptionsForBinary->pszDestDataSource,
                                           psOptionsForBinary->pszFormat);

    }
/* -------------------------------------------------------------------- */
/*      Open data source.                                               */
/* -------------------------------------------------------------------- */

    /* Avoid opening twice the same datasource if it is both the input and output */
    /* Known to cause problems with at least FGdb, SQlite and GPKG drivers. See #4270 */
    if (psOptionsForBinary->eAccessMode != ACCESS_CREATION &&
        strcmp(psOptionsForBinary->pszDestDataSource, psOptionsForBinary->pszDataSource) == 0)
    {
        hODS = GDALOpenEx( psOptionsForBinary->pszDataSource,
                GDAL_OF_UPDATE | GDAL_OF_VECTOR, NULL, psOptionsForBinary->papszOpenOptions, NULL );
        GDALDriverH hDriver = NULL;
        if( hODS != NULL )
            hDriver = GDALGetDatasetDriver(hODS);

        /* Restrict to those 3 drivers. For example it is known to break with */
        /* the PG driver due to the way it manages transactions... */
        if (hDriver && !(EQUAL(GDALGetDescription(hDriver), "FileGDB") ||
                         EQUAL(GDALGetDescription(hDriver), "SQLite") ||
                         EQUAL(GDALGetDescription(hDriver), "GPKG")))
        {
            hDS = GDALOpenEx( psOptionsForBinary->pszDataSource,
                        GDAL_OF_VECTOR, NULL, psOptionsForBinary->papszOpenOptions, NULL );
        }
        else
        {
            hDS = hODS;
            bCloseODS = FALSE;
        }
    }
    else
    {
        hDS = GDALOpenEx( psOptionsForBinary->pszDataSource,
                        GDAL_OF_VECTOR, NULL, psOptionsForBinary->papszOpenOptions, NULL );
    }

/* -------------------------------------------------------------------- */
/*      Report failure                                                  */
/* -------------------------------------------------------------------- */
    if( hDS == NULL )
    {
        OGRSFDriverRegistrar    *poR = OGRSFDriverRegistrar::GetRegistrar();

        fprintf( stderr, "FAILURE:\n"
                "Unable to open datasource `%s' with the following drivers.\n",
                psOptionsForBinary->pszDataSource );

        for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
        {
            fprintf( stderr, "  -> %s\n", poR->GetDriver(iDriver)->GetDescription() );
        }

        GDALVectorTranslateOptionsFree(psOptions);
        GDALVectorTranslateOptionsForBinaryFree(psOptionsForBinary);
        goto exit;
    }

    if( !(psOptionsForBinary->bQuiet) )
    {
        GDALVectorTranslateOptionsSetProgress(psOptions, GDALTermProgress, NULL);
    }

    hDstDS = GDALVectorTranslate(psOptionsForBinary->pszDestDataSource, hODS,
                                              1, &hDS, psOptions, &bUsageError);
    if( bUsageError )
        Usage();
    else
        nRetCode = (hDstDS) ? 0 : 1;

    GDALVectorTranslateOptionsFree(psOptions);
    GDALVectorTranslateOptionsForBinaryFree(psOptionsForBinary);

    if(hDS)
        GDALClose(hDS);
    if(bCloseODS)
        GDALClose(hDstDS);

exit:
    CSLDestroy( papszArgv );
    OGRCleanupAll();

    return nRetCode;
}