Add the ability to process dbsqlfuzz cases in fuzzcheck and add an initial

set of interesting dbsqlfuzz cases.

FossilOrigin-Name: fb9074ff450a67feaa62ca61d19154de26d5c8a8d147409ee6d1fbd667b2914f
This commit is contained in:
drh 2019-01-25 04:00:14 +00:00
parent 813ed78054
commit a47e709e89
7 changed files with 515 additions and 18 deletions

View File

@ -589,7 +589,8 @@ FUZZDATA = \
$(TOP)/test/fuzzdata4.db \
$(TOP)/test/fuzzdata5.db \
$(TOP)/test/fuzzdata6.db \
$(TOP)/test/fuzzdata7.db
$(TOP)/test/fuzzdata7.db \
$(TOP)/test/fuzzdata8.db
# Standard options to testfixture
#
@ -612,6 +613,12 @@ FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
#FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS5
FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPT += -DSQLITE_ENABLE_GEOPOLY
FUZZCHECK_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
DBFUZZ_OPT =

View File

@ -1626,7 +1626,8 @@ FUZZDATA = \
$(TOP)\test\fuzzdata4.db \
$(TOP)\test\fuzzdata5.db \
$(TOP)\test\fuzzdata6.db \
$(TOP)\test\fuzzdata7.db
$(TOP)\test\fuzzdata7.db \
$(TOP)\test\fuzzdata8.db
# <</mark>>
# Additional compiler options for the shell. These are only effective
@ -1644,7 +1645,13 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DESERIALIZE=1
#
MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_GEOPOLY
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DBSTAT_VTAB
FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
@ -1731,10 +1738,10 @@ dbfuzz.exe: $(TOP)\test\dbfuzz.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(DBFUZZ_COMPILE_OPTS) $(TOP)\test\dbfuzz.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
fuzzcheck.exe: $(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
$(LTLINK) $(NO_WARN) $(FUZZCHECK_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
ossshell.exe: $(OSSSHELL_SRC) $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
$(LTLINK) $(NO_WARN) $(FUZZCHECK_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
sessionfuzz.exe: zlib $(TOP)\test\sessionfuzz.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -I$(ZLIBINCDIR) $(TOP)\test\sessionfuzz.c /link $(LDFLAGS) $(LTLINKOPTS) /LIBPATH:$(ZLIBLIBDIR) $(ZLIBLIB)

View File

@ -510,7 +510,8 @@ FUZZDATA = \
$(TOP)/test/fuzzdata4.db \
$(TOP)/test/fuzzdata5.db \
$(TOP)/test/fuzzdata6.db \
$(TOP)/test/fuzzdata7.db
$(TOP)/test/fuzzdata7.db \
$(TOP)/test/fuzzdata8.db
# Standard options to testfixture
#
@ -531,6 +532,11 @@ FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPT += -DSQLITE_ENABLE_GEOPOLY
FUZZCHECK_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
DBFUZZ_OPT =
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
ST_OPT = -DSQLITE_THREADSAFE=0

View File

@ -1,10 +1,10 @@
C Fix\sa\sbuffer\soverread\sin\sfts3\sthat\scould\soccur\sin\sa\sprefix\squery\son\sa\scorrupted\sdatabase.
D 2019-01-24T17:41:12.741
C Add\sthe\sability\sto\sprocess\sdbsqlfuzz\scases\sin\sfuzzcheck\sand\sadd\san\sinitial\nset\sof\sinteresting\sdbsqlfuzz\scases.
D 2019-01-25T04:00:14.721
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in 0e7c107ebcaff26681bc5bcf017557db85aa828d6f7fd652d748b7a78072c298
F Makefile.in 9947eae873c07ae894d4c8633b76c0a0daca7b9fd54401096a77d1a6c7b74359
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc e04060b2138cefc198809d7adad70aebb4a667520b9133fe07a90a1769522dc7
F Makefile.msc 5df60c70edb157feb2148a14c687551969599bd065875a0b959b6b139721ca72
F README.md 377233394b905d3b2e2b33741289e093bc93f2e7adbe00923b2c5958c9a9edee
F VERSION 453e2f4529ca208196d5567db28d549d7151f79efd33f6e6cfe6e613e583a0be
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
@ -436,7 +436,7 @@ F ext/userauth/userauth.c f81aa5a3ecacf406f170c62a144405858f6f6de51dbdc0920134e6
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 468c42acafaf69ae8d514d40cae78343b1d825aabd82e0368f6a3bcf8e4d2469
F main.mk e28b19556f75ba6e841fc9c883d6a3c16edeae2d16d4edf32bf3c150725fc4d8
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@ -984,7 +984,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
F test/fuzzcheck.c 6edb2a0b6c8113cdac10f8e35b891be1a1b08ebacb1c2e2f93876d4d056e8e15
F test/fuzzcheck.c 4082901a0665a5135b295fe81aa0ee325d42e1e28a0e3058a4082d249a321899
F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
@ -992,6 +992,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4
F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5
F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7
F test/fuzzdata7.db 3fc78e65dfe0be9df9e262075d5a335f18f627da47dfc691d1a7b822f34d4b99
F test/fuzzdata8.db 8a96892bd2535578ff2ca27db823b7e149cfce6694c15ca80521fa758be605b1
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
@ -1802,7 +1803,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 2d9cd06715092c312c8c0ec392696a0e90ed090b074e2082e0b830f1399aa941
R aefdd33a1c83587ad3b0becf4339d1cc
U dan
Z df47a0dfd1efad16167473814c8098a6
P d0d5689371577b2861d4a9464443d055f3256f3f51d89e0388233a4cbe2601ee
R a483eb7b902b414248e92f9e64472126
T *branch * dbsqlfuzz-in-fuzzcheck
T *sym-dbsqlfuzz-in-fuzzcheck *
T -sym-trunk *
U drh
Z 174f299274057b1d40bc6ac9348469f7

View File

@ -1 +1 @@
d0d5689371577b2861d4a9464443d055f3256f3f51d89e0388233a4cbe2601ee
fb9074ff450a67feaa62ca61d19154de26d5c8a8d147409ee6d1fbd667b2914f

View File

@ -69,6 +69,7 @@
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include <assert.h>
#include "sqlite3.h"
#define ISSPACE(X) isspace((unsigned char)(X))
#define ISDIGIT(X) isdigit((unsigned char)(X))
@ -400,7 +401,6 @@ static void blobListFree(Blob *p){
}
}
/* Return the current wall-clock time */
static sqlite3_int64 timeOfDay(void){
static sqlite3_vfs *clockVfs = 0;
@ -419,6 +419,448 @@ static sqlite3_int64 timeOfDay(void){
return t;
}
/***************************************************************************
** Code to process combined database+SQL scripts generated by the
** dbsqlfuzz fuzzer.
*/
/* An instance of the following object is passed by pointer as the
** client data to various callbacks.
*/
typedef struct FuzzCtx {
sqlite3 *db; /* The database connection */
sqlite3_int64 iCutoffTime; /* Stop processing at this time. */
sqlite3_int64 iLastCb; /* Time recorded for previous progress callback */
sqlite3_int64 mxInterval; /* Longest interval between two progress calls */
unsigned nCb; /* Number of progress callbacks */
unsigned mxCb; /* Maximum number of progress callbacks allowed */
unsigned execCnt; /* Number of calls to the sqlite3_exec callback */
int timeoutHit; /* True when reaching a timeout */
} FuzzCtx;
/* Verbosity level for the dbsqlfuzz test runner */
static int eVerbosity = 0;
/* True to activate PRAGMA vdbe_debug=on */
static int bVdbeDebug = 0;
/* Timeout for each fuzzing attempt, in milliseconds */
static int iTimeout = 10000; /* Defaults to 10 seconds */
/* Maximum number of progress handler callbacks */
static unsigned int mxProgressCb = 2000;
/* Maximum string length in SQLite */
static int lengthLimit = 1000000;
/* Maximum byte-code program length in SQLite */
static int vdbeOpLimit = 25000;
/* Maximum size of the in-memory database */
static sqlite3_int64 maxDbSize = 104857600;
/*
** Translate a single byte of Hex into an integer.
** This routine only works if h really is a valid hexadecimal
** character: 0..9a..fA..F
*/
static unsigned int hexToInt(unsigned int h){
#ifdef SQLITE_EBCDIC
h += 9*(1&~(h>>4)); /* EBCDIC */
#else
h += 9*(1&(h>>6)); /* ASCII */
#endif
return h & 0xf;
}
/*
** The first character of buffer zIn[0..nIn-1] is a '['. This routine
** checked to see if the buffer holds "[NNNN]" or "[+NNNN]" and if it
** does it makes corresponding changes to the *pK value and *pI value
** and returns true. If the input buffer does not match the patterns,
** no changes are made to either *pK or *pI and this routine returns false.
*/
static int isOffset(
const unsigned char *zIn, /* Text input */
int nIn, /* Bytes of input */
unsigned int *pK, /* half-byte cursor to adjust */
unsigned int *pI /* Input index to adjust */
){
int i;
unsigned int k = 0;
unsigned char c;
for(i=1; i<nIn && (c = zIn[i])!=']'; i++){
if( !isxdigit(c) ) return 0;
k = k*16 + hexToInt(c);
}
if( i==nIn ) return 0;
*pK = 2*k;
*pI += i;
return 1;
}
/*
** Decode the text starting at zIn into a binary database file.
** The maximum length of zIn is nIn bytes. Compute the binary database
** file contain in space obtained from sqlite3_malloc().
**
** Return the number of bytes of zIn consumed. Or return -1 if there
** is an error. One potential error is that the recipe specifies a
** database file larger than MX_FILE_SZ bytes.
**
** Abort on an OOM.
*/
static int decodeDatabase(
const unsigned char *zIn, /* Input text to be decoded */
int nIn, /* Bytes of input text */
unsigned char **paDecode, /* OUT: decoded database file */
int *pnDecode /* OUT: Size of decoded database */
){
unsigned char *a; /* Database under construction */
int mx = 0; /* Current size of the database */
sqlite3_uint64 nAlloc = 4096; /* Space allocated in a[] */
unsigned int i; /* Next byte of zIn[] to read */
unsigned int j; /* Temporary integer */
unsigned int k; /* half-byte cursor index for output */
unsigned int n; /* Number of bytes of input */
unsigned char b = 0;
if( nIn<4 ) return -1;
n = (unsigned int)nIn;
a = sqlite3_malloc( nAlloc );
if( a==0 ){
fprintf(stderr, "Out of memory!\n");
exit(1);
}
memset(a, 0, nAlloc);
for(i=k=0; i<n; i++){
char c = zIn[i];
if( isxdigit(c) ){
k++;
if( k & 1 ){
b = hexToInt(c)*16;
}else{
b += hexToInt(c);
j = k/2 - 1;
if( j>=nAlloc ){
sqlite3_uint64 newSize;
if( nAlloc==MX_FILE_SZ || j>=MX_FILE_SZ ){
if( eVerbosity ){
fprintf(stderr, "Input database too big: max %d bytes\n",
MX_FILE_SZ);
}
sqlite3_free(a);
return -1;
}
newSize = nAlloc*2;
if( newSize<=j ){
newSize = (j+4096)&~4095;
}
if( newSize>MX_FILE_SZ ){
if( j>=MX_FILE_SZ ){
sqlite3_free(a);
return -1;
}
newSize = MX_FILE_SZ;
}
a = sqlite3_realloc( a, newSize );
if( a==0 ){
fprintf(stderr, "Out of memory!\n");
exit(1);
}
assert( newSize > nAlloc );
memset(a+nAlloc, 0, newSize - nAlloc);
nAlloc = newSize;
}
if( j>=(unsigned)mx ){
mx = (j + 4095)&~4095;
if( mx>MX_FILE_SZ ) mx = MX_FILE_SZ;
}
assert( j<nAlloc );
a[j] = b;
}
}else if( zIn[i]=='[' && i<n-3 && isOffset(zIn+i, nIn-i, &k, &i) ){
continue;
}else if( zIn[i]=='\n' && i<n-4 && memcmp(zIn+i,"\n--\n",4)==0 ){
i += 4;
break;
}
}
*pnDecode = mx;
*paDecode = a;
return i;
}
/*
** Progress handler callback.
**
** The argument is the cutoff-time after which all processing should
** stop. So return non-zero if the cut-off time is exceeded.
*/
static int progress_handler(void *pClientData) {
FuzzCtx *p = (FuzzCtx*)pClientData;
sqlite3_int64 iNow = timeOfDay();
int rc = iNow>=p->iCutoffTime;
sqlite3_int64 iDiff = iNow - p->iLastCb;
if( iDiff > p->mxInterval ) p->mxInterval = iDiff;
p->nCb++;
if( rc==0 && p->mxCb>0 && p->mxCb<=p->nCb ) rc = 1;
if( rc && !p->timeoutHit && eVerbosity ){
printf("Timeout on progress callback %d\n", p->nCb);
fflush(stdout);
p->timeoutHit = 1;
}
return rc;
}
/*
** Disallow debugging pragmas such as "PRAGMA vdbe_debug" and
** "PRAGMA parser_trace" since they can dramatically increase the
** amount of output without actually testing anything useful.
**
** Also block ATTACH and DETACH
*/
static int block_troublesome_sql(
void *Notused,
int eCode,
const char *zArg1,
const char *zArg2,
const char *zArg3,
const char *zArg4
){
(void)Notused;
(void)zArg2;
(void)zArg3;
(void)zArg4;
if( eCode==SQLITE_PRAGMA ){
if( sqlite3_strnicmp("vdbe_", zArg1, 5)==0
|| sqlite3_stricmp("parser_trace", zArg1)==0
|| sqlite3_stricmp("temp_store_directory", zArg1)==0
){
return SQLITE_DENY;
}
}else if( (eCode==SQLITE_ATTACH || eCode==SQLITE_DETACH)
&& zArg1 && zArg1[0] ){
return SQLITE_DENY;
}
return SQLITE_OK;
}
/*
** Run the SQL text
*/
static int runDbSql(sqlite3 *db, const char *zSql){
int rc;
sqlite3_stmt *pStmt;
while( isspace(zSql[0]) ) zSql++;
if( zSql[0]==0 ) return SQLITE_OK;
if( eVerbosity>=3 ){
printf("RUNNING-SQL: [%s]\n", zSql);
fflush(stdout);
}
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
if( rc==SQLITE_OK ){
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
if( eVerbosity>=4 ){
int j;
for(j=0; j<sqlite3_column_count(pStmt); j++){
if( j ) printf(",");
switch( sqlite3_column_type(pStmt, j) ){
case SQLITE_NULL: {
printf("NULL");
break;
}
case SQLITE_INTEGER:
case SQLITE_FLOAT: {
printf("%s", sqlite3_column_text(pStmt, j));
break;
}
case SQLITE_BLOB: {
int n = sqlite3_column_bytes(pStmt, j);
int i;
const unsigned char *a;
a = (const unsigned char*)sqlite3_column_blob(pStmt, j);
printf("x'");
for(i=0; i<n; i++){
printf("%02x", a[i]);
}
printf("'");
break;
}
case SQLITE_TEXT: {
int n = sqlite3_column_bytes(pStmt, j);
int i;
const unsigned char *a;
a = (const unsigned char*)sqlite3_column_blob(pStmt, j);
printf("'");
for(i=0; i<n; i++){
if( a[i]=='\'' ){
printf("''");
}else{
putchar(a[i]);
}
}
printf("'");
break;
}
} /* End switch() */
} /* End for() */
printf("\n");
fflush(stdout);
} /* End if( eVerbosity>=4 ) */
} /* End while( SQLITE_ROW */
if( rc!=SQLITE_DONE && eVerbosity>=3 ){
printf("SQL-ERROR: (%d) %s\n", rc, sqlite3_errmsg(db));
fflush(stdout);
}
}else if( eVerbosity>=3 ){
printf("SQL-ERROR (%d): %s\n", rc, sqlite3_errmsg(db));
fflush(stdout);
} /* End if( SQLITE_OK ) */
return sqlite3_finalize(pStmt);
}
/* Invoke this routine to run a single test case */
int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte){
int rc; /* SQLite API return value */
int iSql; /* Index in aData[] of start of SQL */
unsigned char *aDb = 0; /* Decoded database content */
int nDb = 0; /* Size of the decoded database */
int i; /* Loop counter */
int j; /* Start of current SQL statement */
char *zSql = 0; /* SQL text to run */
int nSql; /* Bytes of SQL text */
FuzzCtx cx; /* Fuzzing context */
if( nByte<10 ) return 0;
if( sqlite3_initialize() ) return 0;
if( sqlite3_memory_used()!=0 ){
int nAlloc = 0;
int nNotUsed = 0;
sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &nAlloc, &nNotUsed, 0);
fprintf(stderr,"Memory leak in mutator: %lld bytes in %d allocations\n",
sqlite3_memory_used(), nAlloc);
exit(1);
}
memset(&cx, 0, sizeof(cx));
iSql = decodeDatabase((unsigned char*)aData, (int)nByte, &aDb, &nDb);
if( iSql<0 ) return 0;
nSql = nByte - iSql;
if( eVerbosity>=2 ){
printf(
"****** %d-byte input, %d-byte database, %d-byte script "
"******\n", (int)nByte, nDb, nSql);
fflush(stdout);
}
rc = sqlite3_open(0, &cx.db);
if( rc ) return 1;
if( bVdbeDebug ){
sqlite3_exec(cx.db, "PRAGMA vdbe_debug=ON", 0, 0, 0);
}
/* Invoke the progress handler frequently to check to see if we
** are taking too long. The progress handler will return true
** (which will block further processing) if more than iTimeout seconds have
** elapsed since the start of the test.
*/
cx.iLastCb = timeOfDay();
cx.iCutoffTime = cx.iLastCb + iTimeout; /* Now + iTimeout seconds */
cx.mxCb = mxProgressCb;
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
sqlite3_progress_handler(cx.db, 10, progress_handler, (void*)&cx);
#endif
/* Set a limit on the maximum size of a prepared statement, and the
** maximum length of a string or blob */
if( vdbeOpLimit>0 ){
sqlite3_limit(cx.db, SQLITE_LIMIT_VDBE_OP, vdbeOpLimit);
}
if( lengthLimit>0 ){
sqlite3_limit(cx.db, SQLITE_LIMIT_LENGTH, lengthLimit);
}
if( nDb>=20 && aDb[18]==2 && aDb[19]==2 ){
aDb[18] = aDb[19] = 1;
}
rc = sqlite3_deserialize(cx.db, "main", aDb, nDb, nDb,
SQLITE_DESERIALIZE_RESIZEABLE |
SQLITE_DESERIALIZE_FREEONCLOSE);
if( rc ){
fprintf(stderr, "sqlite3_deserialize() failed with %d\n", rc);
goto testrun_finished;
}
if( maxDbSize>0 ){
sqlite3_int64 x = maxDbSize;
sqlite3_file_control(cx.db, "main", SQLITE_FCNTL_SIZE_LIMIT, &x);
}
/* Block debug pragmas and ATTACH/DETACH. But wait until after
** deserialize to do this because deserialize depends on ATTACH */
sqlite3_set_authorizer(cx.db, block_troublesome_sql, 0);
/* Consistent PRNG seed */
sqlite3_randomness(0,0);
zSql = sqlite3_malloc( nSql + 1 );
if( zSql==0 ){
fprintf(stderr, "Out of memory!\n");
}else{
memcpy(zSql, aData+iSql, nSql);
zSql[nSql] = 0;
for(i=j=0; zSql[i]; i++){
if( zSql[i]==';' ){
char cSaved = zSql[i+1];
zSql[i+1] = 0;
if( sqlite3_complete(zSql+j) ){
rc = runDbSql(cx.db, zSql+j);
j = i+1;
}
zSql[i+1] = cSaved;
if( rc==SQLITE_INTERRUPT || progress_handler(&cx) ){
goto testrun_finished;
}
}
}
if( j<i ){
runDbSql(cx.db, zSql+j);
}
}
testrun_finished:
sqlite3_free(zSql);
rc = sqlite3_close(cx.db);
if( rc!=SQLITE_OK ){
fprintf(stdout, "sqlite3_close() returns %d\n", rc);
}
if( eVerbosity ){
fprintf(stdout, "Peak memory usages: %f MB\n",
sqlite3_memory_highwater(1) / 1000000.0);
}
if( sqlite3_memory_used()!=0 ){
int nAlloc = 0;
int nNotUsed = 0;
sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &nAlloc, &nNotUsed, 0);
fprintf(stderr,"Memory leak: %lld bytes in %d allocations\n",
sqlite3_memory_used(), nAlloc);
exit(1);
}
return 0;
}
/*
** END of the dbsqlfuzz code
***************************************************************************/
/* Look at a SQL text and try to determine if it begins with a database
** description, such as would be found in a dbsqlfuzz test case. Return
** true if this does appear to be a dbsqlfuzz test case and false otherwise.
*/
static int isDbSql(unsigned char *a, int n){
if( n>4 && memcmp(a,"\n--\n",4)==0 ) return 1;
while( n>0 && isspace(a[0]) ){ a++; n--; }
if( n>8 && memcmp(a,"53514c69",8)==0 ) return 1;
return 0;
}
/* Methods for the VHandle object
*/
static int inmemClose(sqlite3_file *pFile){
@ -951,6 +1393,7 @@ int main(int argc, char **argv){
if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
quietFlag = 1;
verboseFlag = 0;
eVerbosity = 0;
}else
if( strcmp(z,"rebuild")==0 ){
rebuildFlag = 1;
@ -976,8 +1419,18 @@ int main(int argc, char **argv){
if( strcmp(z,"verbose")==0 || strcmp(z,"v")==0 ){
quietFlag = 0;
verboseFlag++;
eVerbosity++;
if( verboseFlag>1 ) runFlags |= SQL_TRACE;
}else
if( strcmp(z,"version")==0 ){
int ii;
const char *z;
printf("SQLite %s %s\n", sqlite3_libversion(), sqlite3_sourceid());
for(ii=0; (z = sqlite3_compileoption_get(ii))!=0; ii++){
printf("%s\n", z);
}
return 0;
}else
{
fatalError("unknown option: %s", argv[i]);
}
@ -1230,6 +1683,26 @@ int main(int argc, char **argv){
*/
if( !verboseFlag && !quietFlag ) printf("%s:", zDbName);
for(pSql=g.pFirstSql; pSql; pSql=pSql->pNext){
if( isDbSql(pSql->a, pSql->sz) ){
sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d",pSql->id);
if( verboseFlag ){
printf("%s\n", g.zTestName);
fflush(stdout);
}else if( !quietFlag ){
static int prevAmt = -1;
int idx = pSql->seq;
int amt = idx*10/(g.nSql);
if( amt!=prevAmt ){
printf(" %d%%", amt*10);
fflush(stdout);
prevAmt = amt;
}
}
runCombinedDbSqlInput(pSql->a, pSql->sz);
nTest++;
g.zTestName[0] = 0;
continue;
}
for(pDb=g.pFirstDb; pDb; pDb=pDb->pNext){
int openFlags;
const char *zVfs = "inmem";

BIN
test/fuzzdata8.db Normal file

Binary file not shown.