Add the --script option to fuzzcheck.
FossilOrigin-Name: 5a9676bd4945ca098652780515e94d04859e73588d9db5558ab42f8b068a9ddb
This commit is contained in:
parent
48b4bf269c
commit
075201e50f
12
manifest
12
manifest
@ -1,5 +1,5 @@
|
||||
C Enhance\sfuzzcheck\sso\sthat\sif\san\sargument\sis\san\sordinary\sdisk\sfile\s(not\na\sdatabase)\sit\sis\sread\sin\sand\sprocessed\sas\sa\sscript.
|
||||
D 2021-10-26T22:36:41.583
|
||||
C Add\sthe\s--script\soption\sto\sfuzzcheck.
|
||||
D 2021-10-27T12:05:28.928
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -1055,7 +1055,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c
|
||||
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
|
||||
F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830
|
||||
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
|
||||
F test/fuzzcheck.c b19baffbde9f6b8b3084b8ac3d73bf51a6918078eced6df36d8e0138c91bc4f8
|
||||
F test/fuzzcheck.c c466c078af4476a4f9c6193a9bad5b16966e55bc3c5717b6aa638dea8308c08a
|
||||
F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f
|
||||
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
|
||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||
@ -1929,7 +1929,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 8443a2724f463bd2e14ea3aa337e8987104f63365767ca2b0993f3f3196cff95
|
||||
R da5eebcdd2e37607fde1f372cc816cab
|
||||
P 978dc89df521f5855678128b3c0eb503c67c1b97ddb297076e5f2c03d6297605
|
||||
R 8173569b9fa9f89185b2af54915c96dd
|
||||
U drh
|
||||
Z ca83264146ee66b96c9f2eb230ec2598
|
||||
Z 551daae1722bbf6ff67f95bde9dbd7dc
|
||||
|
@ -1 +1 @@
|
||||
978dc89df521f5855678128b3c0eb503c67c1b97ddb297076e5f2c03d6297605
|
||||
5a9676bd4945ca098652780515e94d04859e73588d9db5558ab42f8b068a9ddb
|
128
test/fuzzcheck.c
128
test/fuzzcheck.c
@ -302,6 +302,77 @@ static VFile *createVFile(const char *zName, int sz, unsigned char *pData){
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/* Return true if the line is all zeros */
|
||||
static int allZero(unsigned char *aLine){
|
||||
int i;
|
||||
for(i=0; i<16 && aLine[i]==0; i++){}
|
||||
return i==16;
|
||||
}
|
||||
|
||||
/*
|
||||
** Render a database and query as text that can be input into
|
||||
** the CLI.
|
||||
*/
|
||||
static void renderDbSqlForCLI(
|
||||
FILE *out, /* Write to this file */
|
||||
const char *zFile, /* Name of the database file */
|
||||
unsigned char *aDb, /* Database content */
|
||||
int nDb, /* Number of bytes in aDb[] */
|
||||
unsigned char *zSql, /* SQL content */
|
||||
int nSql /* Bytes of SQL */
|
||||
){
|
||||
fprintf(out, ".print ******* %s *******\n", zFile);
|
||||
if( nDb>100 ){
|
||||
int i, j; /* Loop counters */
|
||||
int pgsz; /* Size of each page */
|
||||
int lastPage = 0; /* Last page number shown */
|
||||
int iPage; /* Current page number */
|
||||
unsigned char *aLine; /* Single line to display */
|
||||
unsigned char buf[16]; /* Fake line */
|
||||
unsigned char bShow[256]; /* Characters ok to display */
|
||||
|
||||
memset(bShow, '.', sizeof(bShow));
|
||||
for(i=' '; i<='~'; i++){
|
||||
if( i!='{' && i!='}' && i!='"' && i!='\\' ) bShow[i] = i;
|
||||
}
|
||||
pgsz = (aDb[16]<<8) | aDb[17];
|
||||
if( pgsz==0 ) pgsz = 65536;
|
||||
if( pgsz<512 || (pgsz&(pgsz-1))!=0 ) pgsz = 4096;
|
||||
fprintf(out,".open --hexdb\n");
|
||||
fprintf(out,"| size %d pagesize %d filename %s\n",nDb,pgsz,zFile);
|
||||
for(i=0; i<nDb; i += 16){
|
||||
if( i+16>nDb ){
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memcpy(buf, aDb+i, nDb-i);
|
||||
aLine = buf;
|
||||
}else{
|
||||
aLine = aDb + i;
|
||||
}
|
||||
if( allZero(aLine) ) continue;
|
||||
iPage = i/pgsz + 1;
|
||||
if( lastPage!=iPage ){
|
||||
fprintf(out,"| page %d offset %d\n", iPage, (iPage-1)*pgsz);
|
||||
lastPage = iPage;
|
||||
}
|
||||
fprintf(out,"| %5d:", i-(iPage-1)*pgsz);
|
||||
for(j=0; j<16; j++) fprintf(out," %02x", aLine[j]);
|
||||
fprintf(out," ");
|
||||
for(j=0; j<16; j++){
|
||||
unsigned char c = (unsigned char)aLine[j];
|
||||
fputc( bShow[c], stdout);
|
||||
}
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
fprintf(out,"| end %s\n", zFile);
|
||||
}else{
|
||||
fprintf(out,".open :memory:\n");
|
||||
}
|
||||
fprintf(out,".testctrl prng_seed 1 db\n");
|
||||
fprintf(out,".testctrl internal_functions\n");
|
||||
fprintf(out,"%.*s", nSql, zSql);
|
||||
if( nSql>0 && zSql[nSql-1]!='\n' ) fprintf(out, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
** Read the complete content of a file into memory. Add a 0x00 terminator
|
||||
** and return a pointer to the result.
|
||||
@ -325,7 +396,7 @@ static char *readFile(const char *zFilename, long *sz){
|
||||
if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
|
||||
pBuf[nIn] = 0;
|
||||
fclose(in);
|
||||
return pBuf;
|
||||
return (char*)pBuf;
|
||||
}
|
||||
sqlite3_free(pBuf);
|
||||
*sz = 0;
|
||||
@ -876,7 +947,13 @@ static int runDbSql(sqlite3 *db, const char *zSql){
|
||||
}
|
||||
|
||||
/* Invoke this routine to run a single test case */
|
||||
int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte, int iTimeout){
|
||||
int runCombinedDbSqlInput(
|
||||
const uint8_t *aData, /* Combined DB+SQL content */
|
||||
size_t nByte, /* Size of aData in bytes */
|
||||
int iTimeout, /* Use this timeout */
|
||||
int bScript, /* If true, just render CLI output */
|
||||
int iSqlId /* SQL identifier */
|
||||
){
|
||||
int rc; /* SQLite API return value */
|
||||
int iSql; /* Index in aData[] of start of SQL */
|
||||
unsigned char *aDb = 0; /* Decoded database content */
|
||||
@ -902,6 +979,14 @@ int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte, int iTimeout){
|
||||
iSql = decodeDatabase((unsigned char*)aData, (int)nByte, &aDb, &nDb);
|
||||
if( iSql<0 ) return 0;
|
||||
nSql = (int)(nByte - iSql);
|
||||
if( bScript ){
|
||||
char zName[100];
|
||||
sqlite3_snprintf(sizeof(zName),zName,"dbsql%06d.db",iSqlId);
|
||||
renderDbSqlForCLI(stdout, zName, aDb, nDb,
|
||||
(unsigned char*)(aData+iSql), nSql);
|
||||
sqlite3_free(aDb);
|
||||
return 0;
|
||||
}
|
||||
if( eVerbosity>=3 ){
|
||||
printf(
|
||||
"****** %d-byte input, %d-byte database, %d-byte script "
|
||||
@ -1005,7 +1090,7 @@ testrun_finished:
|
||||
if( rc!=SQLITE_OK ){
|
||||
fprintf(stdout, "sqlite3_close() returns %d\n", rc);
|
||||
}
|
||||
if( eVerbosity>=2 ){
|
||||
if( eVerbosity>=2 && !bScript ){
|
||||
fprintf(stdout, "Peak memory usages: %f MB\n",
|
||||
sqlite3_memory_highwater(1) / 1000000.0);
|
||||
}
|
||||
@ -1479,6 +1564,7 @@ static void showHelp(void){
|
||||
" -q|--quiet Reduced output\n"
|
||||
" --rebuild Rebuild and vacuum the database file\n"
|
||||
" --result-trace Show the results of each SQL command\n"
|
||||
" --script Output CLI script instead of running tests\n"
|
||||
" --skip N Skip the first N test cases\n"
|
||||
" --spinner Use a spinner to show progress\n"
|
||||
" --sqlid N Use only SQL where sqlid=N\n"
|
||||
@ -1508,6 +1594,7 @@ int main(int argc, char **argv){
|
||||
int vdbeLimitFlag = 0; /* --limit-vdbe */
|
||||
int infoFlag = 0; /* --info */
|
||||
int nSkip = 0; /* --skip */
|
||||
int bScript = 0; /* --script */
|
||||
int bSpinner = 0; /* True for --spinner */
|
||||
int timeoutTest = 0; /* undocumented --timeout-test flag */
|
||||
int runFlags = 0; /* Flags sent to runSql() */
|
||||
@ -1642,6 +1729,9 @@ int main(int argc, char **argv){
|
||||
if( strcmp(z,"result-trace")==0 ){
|
||||
runFlags |= SQL_OUTPUT;
|
||||
}else
|
||||
if( strcmp(z,"script")==0 ){
|
||||
bScript = 1;
|
||||
}else
|
||||
if( strcmp(z,"skip")==0 ){
|
||||
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
|
||||
nSkip = atoi(argv[++i]);
|
||||
@ -1930,7 +2020,7 @@ int main(int argc, char **argv){
|
||||
}
|
||||
|
||||
/* Print the description, if there is one */
|
||||
if( !quietFlag ){
|
||||
if( !quietFlag && !bScript ){
|
||||
zDbName = azSrcDb[iSrcDb];
|
||||
i = (int)strlen(zDbName) - 1;
|
||||
while( i>0 && zDbName[i-1]!='/' && zDbName[i-1]!='\\' ){ i--; }
|
||||
@ -1987,12 +2077,16 @@ int main(int argc, char **argv){
|
||||
|
||||
/* Run a test using each SQL script against each database.
|
||||
*/
|
||||
if( !verboseFlag && !quietFlag && !bSpinner ) printf("%s:", zDbName);
|
||||
if( !verboseFlag && !quietFlag && !bSpinner && !bScript ){
|
||||
printf("%s:", zDbName);
|
||||
}
|
||||
for(pSql=g.pFirstSql; pSql; pSql=pSql->pNext){
|
||||
tmStart = timeOfDay();
|
||||
if( isDbSql(pSql->a, pSql->sz) ){
|
||||
sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d",pSql->id);
|
||||
if( bSpinner ){
|
||||
if( bScript ){
|
||||
/* No progress output */
|
||||
}else if( bSpinner ){
|
||||
int nTotal =g.nSql;
|
||||
int idx = pSql->seq;
|
||||
printf("\r%s: %d/%d ", zDbName, idx, nTotal);
|
||||
@ -2013,10 +2107,10 @@ int main(int argc, char **argv){
|
||||
if( nSkip>0 ){
|
||||
nSkip--;
|
||||
}else{
|
||||
runCombinedDbSqlInput(pSql->a, pSql->sz, iTimeout);
|
||||
runCombinedDbSqlInput(pSql->a, pSql->sz, iTimeout, bScript, pSql->id);
|
||||
}
|
||||
nTest++;
|
||||
if( bTimer ){
|
||||
if( bTimer && !bScript ){
|
||||
sqlite3_int64 tmEnd = timeOfDay();
|
||||
printf("%lld %s\n", tmEnd - tmStart, g.zTestName);
|
||||
}
|
||||
@ -2029,7 +2123,9 @@ int main(int argc, char **argv){
|
||||
const char *zVfs = "inmem";
|
||||
sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d,dbid=%d",
|
||||
pSql->id, pDb->id);
|
||||
if( bSpinner ){
|
||||
if( bScript ){
|
||||
/* No progress output */
|
||||
}else if( bSpinner ){
|
||||
int nTotal = g.nDb*g.nSql;
|
||||
int idx = pSql->seq*g.nDb + pDb->id - 1;
|
||||
printf("\r%s: %d/%d ", zDbName, idx, nTotal);
|
||||
@ -2051,6 +2147,14 @@ int main(int argc, char **argv){
|
||||
nSkip--;
|
||||
continue;
|
||||
}
|
||||
if( bScript ){
|
||||
char zName[100];
|
||||
sqlite3_snprintf(sizeof(zName), zName, "db%06d.db",
|
||||
pDb->id>1 ? pDb->id : pSql->id);
|
||||
renderDbSqlForCLI(stdout, zName,
|
||||
pDb->a, pDb->sz, pSql->a, pSql->sz);
|
||||
continue;
|
||||
}
|
||||
createVFile("main.db", pDb->sz, pDb->a);
|
||||
sqlite3_randomness(0,0);
|
||||
if( ossFuzzThisDb ){
|
||||
@ -2123,7 +2227,9 @@ int main(int argc, char **argv){
|
||||
}
|
||||
}
|
||||
}
|
||||
if( bSpinner ){
|
||||
if( bScript ){
|
||||
/* No progress output */
|
||||
}else if( bSpinner ){
|
||||
int nTotal = g.nDb*g.nSql;
|
||||
printf("\r%s: %d/%d \n", zDbName, nTotal, nTotal);
|
||||
}else if( !quietFlag && !verboseFlag ){
|
||||
@ -2139,7 +2245,7 @@ int main(int argc, char **argv){
|
||||
|
||||
} /* End loop over all source databases */
|
||||
|
||||
if( !quietFlag ){
|
||||
if( !quietFlag && !bScript ){
|
||||
sqlite3_int64 iElapse = timeOfDay() - iBegin;
|
||||
printf("fuzzcheck: 0 errors out of %d tests in %d.%03d seconds\n"
|
||||
"SQLite %s %s\n",
|
||||
|
Loading…
Reference in New Issue
Block a user