From: drh Date: Fri, 1 May 2015 19:21:12 +0000 (+0000) Subject: Enhance fuzzershell to accept multiple input files. Add the test/fuzzdata2.txt X-Git-Tag: version-3.8.10~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b3df0c675cc08a2c9a5227f00091349ef2a13151;p=thirdparty%2Fsqlite.git Enhance fuzzershell to accept multiple input files. Add the test/fuzzdata2.txt fuzz test content. FossilOrigin-Name: ab5523aafe4817232388d28ea99be0953e7dccf3 --- diff --git a/Makefile.in b/Makefile.in index 116f117bbb..fbf67bdf6d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -964,7 +964,7 @@ fulltestonly: testfixture$(TEXE) sqlite3$(TEXE) # Fuzz testing fuzztest: fuzzershell$(TEXE) - ./fuzzershell$(TEXE) -f $(TOP)/test/fuzzdata1.txt + ./fuzzershell$(TEXE) $(TOP)/test/fuzzdata1.txt $(TOP)/test/fuzzdata2.txt fuzzoomtest: fuzzershell$(TEXE) ./fuzzershell$(TEXE) -f $(TOP)/test/fuzzdata1.txt --oom diff --git a/Makefile.msc b/Makefile.msc index 512de51c78..9ccc7ea5fc 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1644,7 +1644,7 @@ queryplantest: testfixture.exe sqlite3.exe .\testfixture.exe $(TOP)\test\permutations.test queryplanner fuzztest: fuzzershell.exe - .\fuzzershell.exe -f $(TOP)\test\fuzzdata1.txt + .\fuzzershell.exe $(TOP)\test\fuzzdata1.txt $(TOP)\test\fuzzdata2.txt fuzzoomtest: fuzzershell.exe .\fuzzershell.exe -f $(TOP)\test\fuzzdata1.txt --oom diff --git a/main.mk b/main.mk index 6c73fa4943..53eff03012 100644 --- a/main.mk +++ b/main.mk @@ -646,7 +646,7 @@ queryplantest: testfixture$(EXE) sqlite3$(EXE) ./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner fuzztest: fuzzershell$(EXE) - ./fuzzershell$(EXE) -f $(TOP)/test/fuzzdata1.txt + ./fuzzershell$(EXE) $(TOP)/test/fuzzdata1.txt $(TOP)/test/fuzzdata2.txt fuzzoomtest: fuzzershell$(EXE) ./fuzzershell$(EXE) -f $(TOP)/test/fuzzdata1.txt --oom diff --git a/manifest b/manifest index a069ec6ab1..db9d4f7a21 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\san\sassert\sin\sRTREE\sthat\swould\sfire\sif\sthe\srtree\stable\sis\smisdeclared. -D 2015-05-01T18:00:37.511 +C Enhance\sfuzzershell\sto\saccept\smultiple\sinput\sfiles.\s\sAdd\sthe\stest/fuzzdata2.txt\nfuzz\stest\scontent. +D 2015-05-01T19:21:12.995 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in e3268d234210842b4be0a6e2e1c5990999f1d9f4 +F Makefile.in e628c50e237251fc7e768bef14ee7e822ad69e69 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc d80278757ef0b02d797d6ab98e07baf9c608b1a2 +F Makefile.msc 4c7e6fc40c5b65134b789b18b83743abac907504 F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858 F README.md d58e3bebc0a4145e0f2a87994015fdb575a8e866 F VERSION 2e244662b71e6e68a5c29b014ebc5b7564f4cc5a @@ -152,7 +152,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk c0c7503b9749c1532c1e0e9501331abc1afc299d +F main.mk 1225d45e1883000a3ed6f028893a11c04522ea6a F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea F mkopcodeh.awk d5e22023b5238985bb54a72d33e0ac71fe4f8a32 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 @@ -632,6 +632,7 @@ F test/fuzz3.test efd384b896c647b61a2c1848ba70d42aad60a7b3 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 F test/fuzzdata1.txt 9fceb50868e0b798160e83742bd7e44e457176a0 +F test/fuzzdata2.txt ba9b4467d7ec46cc85d32c0d031540cd727ae6ad F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 @@ -1207,7 +1208,7 @@ F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1 F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 -F tool/fuzzershell.c 2799d1e74c48a7fbbfc4889601005d42d1e237a5 +F tool/fuzzershell.c 32816d2c54e7243504ab8af6d9b4323ed1206342 F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce @@ -1255,7 +1256,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 40db3e40126db1035fcc12989026915744dc5651 -R d52749e43e60b570f31909140ed0a510 +P 9a45409cc4078f2b6e68aa777f6ab86a14309833 +R 3a133cb00e1f62fffce773de23d1e308 U drh -Z 292f5446ecb0ed9f640d81ad4e3c067d +Z 8894bd22b6f91dc8094aac398d313abb diff --git a/manifest.uuid b/manifest.uuid index 8283d0b2ef..2765b25987 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a45409cc4078f2b6e68aa777f6ab86a14309833 \ No newline at end of file +ab5523aafe4817232388d28ea99be0953e7dccf3 \ No newline at end of file diff --git a/test/fuzzdata2.txt b/test/fuzzdata2.txt new file mode 100644 index 0000000000..b1d4bb7bb1 Binary files /dev/null and b/test/fuzzdata2.txt differ diff --git a/tool/fuzzershell.c b/tool/fuzzershell.c index a464e6873a..546458a731 100644 --- a/tool/fuzzershell.c +++ b/tool/fuzzershell.c @@ -315,15 +315,14 @@ static void sqlEvalFunc( ** Print sketchy documentation for this utility program */ static void showHelp(void){ - printf("Usage: %s [options]\n", g.zArgv0); + printf("Usage: %s [options] ?FILE...?\n", g.zArgv0); printf( -"Read SQL text from standard input and evaluate it.\n" +"Read SQL text from FILE... (or from standard input if FILE... is omitted)\n" +"and then evaluate each block of SQL contained therein.\n" "Options:\n" " --autovacuum Enable AUTOVACUUM mode\n" -" -f FILE Read SQL text from FILE instead of standard input\n" " --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n" " --help Show this help text\n" -" --initdb DBFILE Initialize the in-memory database using template DBFILE\n" " --lookaside N SZ Configure lookaside for N slots of SZ bytes each\n" " --oom Run each test multiple times in a simulated OOM loop\n" " --pagesize N Set the page size to N\n" @@ -397,28 +396,17 @@ static int integerValue(const char *zArg){ return (int)(isNeg? -v : v); } -/* -** Various operating modes -*/ -#define FZMODE_Generic 1 -#define FZMODE_Strftime 2 -#define FZMODE_Printf 3 -#define FZMODE_Glob 4 - int main(int argc, char **argv){ - char *zIn = 0; /* Input text */ - int nAlloc = 0; /* Number of bytes allocated for zIn[] */ - int nIn = 0; /* Number of bytes of zIn[] used */ - size_t got; /* Bytes read from input */ - FILE *in = stdin; /* Where to read SQL text from */ - int rc = SQLITE_OK; /* Result codes from API functions */ - int i; /* Loop counter */ - int iNext; /* Next block of SQL */ - sqlite3 *db; /* Open database */ - sqlite3 *dbInit = 0; /* On-disk database used to initialize the in-memory db */ - const char *zInitDb = 0;/* Name of the initialization database file */ - char *zErrMsg = 0; /* Error message returned from sqlite3_exec() */ + char *zIn = 0; /* Input text */ + int nAlloc = 0; /* Number of bytes allocated for zIn[] */ + int nIn = 0; /* Number of bytes of zIn[] used */ + size_t got; /* Bytes read from input */ + int rc = SQLITE_OK; /* Result codes from API functions */ + int i; /* Loop counter */ + int iNext; /* Next block of SQL */ + sqlite3 *db; /* Open database */ + char *zErrMsg = 0; /* Error message returned from sqlite3_exec() */ const char *zEncoding = 0; /* --utf16be or --utf16le */ int nHeap = 0, mnHeap = 0; /* Heap size from --heap */ int nLook = 0, szLook = 0; /* --lookaside configuration */ @@ -432,7 +420,6 @@ int main(int argc, char **argv){ int doAutovac = 0; /* True for --autovacuum */ char *zSql; /* SQL to run */ char *zToFree = 0; /* Call sqlite3_free() on this afte running zSql */ - int iMode = FZMODE_Generic; /* Operating mode */ const char *zCkGlob = 0; /* Inputs must match this glob */ int verboseFlag = 0; /* --verbose or -v flag */ int quietFlag = 0; /* --quiet or -q flag */ @@ -447,10 +434,15 @@ int main(int argc, char **argv){ int oomCnt = 0; /* Counter for the OOM loop */ char zErrBuf[200]; /* Space for the error message */ const char *zFailCode; /* Value of the TEST_FAILURE environment var */ + const char *zPrompt; /* Initial prompt when large-file fuzzing */ + int nInFile = 0; /* Number of input files to read */ + char **azInFile = 0; /* Array of input file names */ + int jj; /* Loop counter for azInFile[] */ zFailCode = getenv("TEST_FAILURE"); g.zArgv0 = argv[0]; + zPrompt = ""; for(i=1; i=argc-2 ) abendError("missing arguments on %s\n", argv[i]); @@ -474,35 +465,12 @@ int main(int argc, char **argv){ showHelp(); return 0; }else - if( strcmp(z, "initdb")==0 && i+1=argc-2 ) abendError("missing arguments on %s", argv[i]); nLook = integerValue(argv[i+1]); szLook = integerValue(argv[i+2]); i += 2; }else - if( strcmp(z,"mode")==0 ){ - if( i>=argc-1 ) abendError("missing argument on %s", argv[i]); - z = argv[++i]; - if( strcmp(z,"generic")==0 ){ - iMode = FZMODE_Printf; - zCkGlob = 0; - }else if( strcmp(z, "glob")==0 ){ - iMode = FZMODE_Glob; - zCkGlob = "'*','*'"; - }else if( strcmp(z, "printf")==0 ){ - iMode = FZMODE_Printf; - zCkGlob = "'*',*"; - }else if( strcmp(z, "strftime")==0 ){ - iMode = FZMODE_Strftime; - zCkGlob = "'*',*"; - }else{ - abendError("unknown --mode: %s", z); - } - }else if( strcmp(z,"oom")==0 ){ oomFlag = 1; }else @@ -545,9 +513,15 @@ int main(int argc, char **argv){ abendError("unknown option: %s", argv[i]); } }else{ - abendError("unknown argument: %s", argv[i]); + addNewInFile: + nInFile++; + azInFile = realloc(azInFile, sizeof(azInFile[0])*nInFile); + if( azInFile==0 ) abendError("out of memory"); + azInFile[nInFile-1] = argv[i]; } } + + /* Do global SQLite initialization */ sqlite3_config(SQLITE_CONFIG_LOG, verboseFlag ? shellLog : shellLogNoop, 0); if( nHeap>0 ){ pHeap = malloc( nHeap ); @@ -583,209 +557,245 @@ int main(int argc, char **argv){ rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache); if( rc ) abendError("pcache configuration failed: %d", rc); } - while( !feof(in) ){ - nAlloc += nAlloc+1000; - zIn = realloc(zIn, nAlloc); - if( zIn==0 ) fatalError("out of memory"); - got = fread(zIn+nIn, 1, nAlloc-nIn-1, in); - nIn += (int)got; - zIn[nIn] = 0; - if( got==0 ) break; - } - if( in!=stdin ) fclose(in); + + /* If the --unique-cases option was supplied, open the database that will + ** be used to gather unique test cases. + */ if( zDataOut ){ rc = sqlite3_open(":memory:", &dataDb); if( rc ) abendError("cannot open :memory: database"); rc = sqlite3_exec(dataDb, "CREATE TABLE testcase(sql BLOB PRIMARY KEY) WITHOUT ROWID;",0,0,0); if( rc ) abendError("%s", sqlite3_errmsg(dataDb)); - rc = sqlite3_prepare_v2(dataDb, "INSERT OR IGNORE INTO testcase(sql)VALUES(?1)", - -1, &pStmt, 0); + rc = sqlite3_prepare_v2(dataDb, + "INSERT OR IGNORE INTO testcase(sql)VALUES(?1)", + -1, &pStmt, 0); if( rc ) abendError("%s", sqlite3_errmsg(dataDb)); } - if( zInitDb ){ - rc = sqlite3_open_v2(zInitDb, &dbInit, SQLITE_OPEN_READONLY, 0); - if( rc!=SQLITE_OK ){ - abendError("unable to open initialization database \"%s\"", zInitDb); - } - } - for(i=0; i****/"); - if( z ){ - z += 6; - sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "%.*s", - (int)(z-&zIn[i]) - 12, &zIn[i+6]); - if( verboseFlag ){ - printf("%.*s\n", (int)(z-&zIn[i]), &zIn[i]); - fflush(stdout); - } - i += (int)(z-&zIn[i]); - multiTest = 1; + + /* Initialize the input buffer used to hold SQL text */ + if( nInFile==0 ) nInFile = 1; + nAlloc = 1000; + zIn = malloc(nAlloc); + if( zIn==0 ) fatalError("out of memory"); + + /* Loop over all input files */ + for(jj=0; jj****/"); + if( z ){ + z += 6; + sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "%.*s", + (int)(z-&zIn[i]) - 12, &zIn[i+6]); + if( verboseFlag ){ + printf("%.*s\n", (int)(z-&zIn[i]), &zIn[i]); + fflush(stdout); + } + i += (int)(z-&zIn[i]); + multiTest = 1; } } - } - fflush(stdout); - switch( iMode ){ - case FZMODE_Glob: - zSql = zToFree = sqlite3_mprintf("SELECT glob(%s);", zSql); - break; - case FZMODE_Printf: - zSql = zToFree = sqlite3_mprintf("SELECT printf(%s);", zSql); - break; - case FZMODE_Strftime: - zSql = zToFree = sqlite3_mprintf("SELECT strftime(%s);", zSql); - break; - } - if( oomFlag ){ - oomCnt = g.iOomCntdown = 1; - g.nOomFault = 0; - g.bOomOnce = 1; - if( verboseFlag ){ - printf("Once.%d\n", oomCnt); - fflush(stdout); + for(iNext=i; iNext0 ){ - abendError("memory in use after close: %lld bytes", sqlite3_memory_used()); - } - if( oomFlag ){ - /* Limit the number of iterations of the OOM loop to OOM_MAX. If the - ** first pass (single failure) exceeds 2/3rds of OOM_MAX this skip the - ** second pass (continuous failure after first) completely. */ - if( g.nOomFault==0 || oomCnt>OOM_MAX ){ - if( g.bOomOnce && oomCnt<=(OOM_MAX*2/3) ){ - oomCnt = g.iOomCntdown = 1; - g.bOomOnce = 0; + g.bOomEnable = 0; + rc = sqlite3_close(db); + if( rc ){ + abendError("sqlite3_close() failed with rc=%d", rc); + } + if( sqlite3_memory_used()>0 ){ + abendError("memory in use after close: %lld bytes",sqlite3_memory_used()); + } + if( oomFlag ){ + /* Limit the number of iterations of the OOM loop to OOM_MAX. If the + ** first pass (single failure) exceeds 2/3rds of OOM_MAX this skip the + ** second pass (continuous failure after first) completely. */ + if( g.nOomFault==0 || oomCnt>OOM_MAX ){ + if( g.bOomOnce && oomCnt<=(OOM_MAX*2/3) ){ + oomCnt = g.iOomCntdown = 1; + g.bOomOnce = 0; + }else{ + oomCnt = 0; + } }else{ - oomCnt = 0; + g.iOomCntdown = ++oomCnt; + g.nOomFault = 0; } - }else{ - g.iOomCntdown = ++oomCnt; - g.nOomFault = 0; - } - if( oomCnt ){ - if( verboseFlag ){ - printf("%s.%d\n", g.bOomOnce ? "Once" : "Multi", oomCnt); - fflush(stdout); + if( oomCnt ){ + if( verboseFlag ){ + printf("%s.%d\n", g.bOomOnce ? "Once" : "Multi", oomCnt); + fflush(stdout); + } + nTest++; } - nTest++; } + }while( oomCnt>0 ); + + /* Free the SQL from the current test case + */ + if( zToFree ){ + sqlite3_free(zToFree); + zToFree = 0; } - }while( oomCnt>0 ); - if( zToFree ){ - sqlite3_free(zToFree); - zToFree = 0; - } - zIn[iNext] = cSaved; - if( verboseFlag ){ - printf("RESULT-CODE: %d\n", rc); - if( zErrMsg ){ - printf("ERROR-MSG: [%s]\n", zErrBuf); + zIn[iNext] = cSaved; + + /* Show test-case results in --verbose mode + */ + if( verboseFlag ){ + printf("RESULT-CODE: %d\n", rc); + if( zErrMsg ){ + printf("ERROR-MSG: [%s]\n", zErrBuf); + } + fflush(stdout); } - fflush(stdout); - } - /* Simulate an error if the TEST_FAILURE environment variable is "5" */ - if( zFailCode ){ - if( zFailCode[0]=='5' && zFailCode[1]==0 ){ - abendError("simulated failure"); - }else if( zFailCode[0]!=0 ){ - /* If TEST_FAILURE is something other than 5, just exit the test - ** early */ - printf("\nExit early due to TEST_FAILURE being set"); - break; + + /* Simulate an error if the TEST_FAILURE environment variable is "5". + ** This is used to verify that automated test script really do spot + ** errors that occur in this test program. + */ + if( zFailCode ){ + if( zFailCode[0]=='5' && zFailCode[1]==0 ){ + abendError("simulated failure"); + }else if( zFailCode[0]!=0 ){ + /* If TEST_FAILURE is something other than 5, just exit the test + ** early */ + printf("\nExit early due to TEST_FAILURE being set"); + break; + } } } + if( !verboseFlag && multiTest && !quietFlag && !oomFlag ) printf("\n"); } - if( !verboseFlag && multiTest && !quietFlag && !oomFlag ) printf("\n"); + + /* Report total number of tests run + */ if( nTest>1 && !quietFlag ){ printf("%s: 0 errors out of %d tests\nSQLite %s %s\n", g.zArgv0, nTest, sqlite3_libversion(), sqlite3_sourceid()); } + + /* Write the unique test cases if the --unique-cases flag was used + */ if( zDataOut ){ int n = 0; FILE *out = fopen(zDataOut, "wb"); @@ -802,6 +812,10 @@ int main(int argc, char **argv){ sqlite3_finalize(pStmt); sqlite3_close(dataDb); } + + /* Clean up and exit. + */ + free(azInFile); free(zIn); free(pHeap); free(pLook);