xref: /sqlite-3.40.0/tool/fuzzershell.c (revision 8ea5eca1)
1 /*
2 ** 2015-04-17
3 **
4 ** The author disclaims copyright to this source code.  In place of
5 ** a legal notice, here is a blessing:
6 **
7 **    May you do good and not evil.
8 **    May you find forgiveness for yourself and forgive others.
9 **    May you share freely, never taking more than you give.
10 **
11 *************************************************************************
12 **
13 ** This is a utility program designed to aid running the SQLite library
14 ** against an external fuzzer, such as American Fuzzy Lop (AFL)
15 ** (http://lcamtuf.coredump.cx/afl/).  Basically, this program reads
16 ** SQL text from standard input and passes it through to SQLite for evaluation,
17 ** just like the "sqlite3" command-line shell.  Differences from the
18 ** command-line shell:
19 **
20 **    (1)  The complex "dot-command" extensions are omitted.  This
21 **         prevents the fuzzer from discovering that it can run things
22 **         like ".shell rm -rf ~"
23 **
24 **    (2)  The database is opened with the SQLITE_OPEN_MEMORY flag so that
25 **         no disk I/O from the database is permitted.  The ATTACH command
26 **         with a filename still uses an in-memory database.
27 **
28 **    (3)  The main in-memory database can be initialized from a template
29 **         disk database so that the fuzzer starts with a database containing
30 **         content.
31 **
32 **    (4)  The eval() SQL function is added, allowing the fuzzer to do
33 **         interesting recursive operations.
34 **
35 ** 2015-04-20: The input text can be divided into separate SQL chunks using
36 ** lines of the form:
37 **
38 **       |****<...>****|
39 **
40 ** where the "..." is arbitrary text, except the "|" should really be "/".
41 ** ("|" is used here to avoid compiler warnings about nested comments.)
42 ** A separate in-memory SQLite database is created to run each chunk of SQL.
43 ** This feature allows the "queue" of AFL to be captured into a single big
44 ** file using a command like this:
45 **
46 **    (for i in id:*; do echo '|****<'$i'>****|'; cat $i; done) >~/all-queue.txt
47 **
48 ** (Once again, change the "|" to "/") Then all elements of the AFL queue
49 ** can be run in a single go (for regression testing, for example) by typing:
50 **
51 **    fuzzershell -f ~/all-queue.txt
52 **
53 ** After running each chunk of SQL, the database connection is closed.  The
54 ** program aborts if the close fails or if there is any unfreed memory after
55 ** the close.
56 **
57 ** New cases can be appended to all-queue.txt at any time.  If redundant cases
58 ** are added, that can be eliminated by running:
59 **
60 **    fuzzershell -f ~/all-queue.txt --unique-cases ~/unique-cases.txt
61 **
62 */
63 #include <stdio.h>
64 #include <stdlib.h>
65 #include <string.h>
66 #include <stdarg.h>
67 #include <ctype.h>
68 #include "sqlite3.h"
69 
70 /*
71 ** All global variables are gathered into the "g" singleton.
72 */
73 struct GlobalVars {
74   const char *zArgv0;         /* Name of program */
75 } g;
76 
77 
78 
79 /*
80 ** Print an error message and abort in such a way to indicate to the
81 ** fuzzer that this counts as a crash.
82 */
83 static void abendError(const char *zFormat, ...){
84   va_list ap;
85   fprintf(stderr, "%s: ", g.zArgv0);
86   va_start(ap, zFormat);
87   vfprintf(stderr, zFormat, ap);
88   va_end(ap);
89   fprintf(stderr, "\n");
90   abort();
91 }
92 /*
93 ** Print an error message and quit, but not in a way that would look
94 ** like a crash.
95 */
96 static void fatalError(const char *zFormat, ...){
97   va_list ap;
98   fprintf(stderr, "%s: ", g.zArgv0);
99   va_start(ap, zFormat);
100   vfprintf(stderr, zFormat, ap);
101   va_end(ap);
102   fprintf(stderr, "\n");
103   exit(1);
104 }
105 
106 /*
107 ** Evaluate some SQL.  Abort if unable.
108 */
109 static void sqlexec(sqlite3 *db, const char *zFormat, ...){
110   va_list ap;
111   char *zSql;
112   char *zErrMsg = 0;
113   int rc;
114   va_start(ap, zFormat);
115   zSql = sqlite3_vmprintf(zFormat, ap);
116   va_end(ap);
117   rc = sqlite3_exec(db, zSql, 0, 0, &zErrMsg);
118   if( rc ) abendError("failed sql [%s]: %s", zSql, zErrMsg);
119   sqlite3_free(zSql);
120 }
121 
122 /*
123 ** This callback is invoked by sqlite3_log().
124 */
125 static void shellLog(void *pNotUsed, int iErrCode, const char *zMsg){
126   printf("LOG: (%d) %s\n", iErrCode, zMsg);
127 }
128 
129 /*
130 ** This callback is invoked by sqlite3_exec() to return query results.
131 */
132 static int execCallback(void *NotUsed, int argc, char **argv, char **colv){
133   int i;
134   static unsigned cnt = 0;
135   printf("ROW #%u:\n", ++cnt);
136   for(i=0; i<argc; i++){
137     printf(" %s=", colv[i]);
138     if( argv[i] ){
139       printf("[%s]\n", argv[i]);
140     }else{
141       printf("NULL\n");
142     }
143   }
144   return 0;
145 }
146 static int execNoop(void *NotUsed, int argc, char **argv, char **colv){
147   return 0;
148 }
149 
150 /*
151 ** This callback is invoked by sqlite3_trace() as each SQL statement
152 ** starts.
153 */
154 static void traceCallback(void *NotUsed, const char *zMsg){
155   printf("TRACE: %s\n", zMsg);
156 }
157 
158 /***************************************************************************
159 ** eval() implementation copied from ../ext/misc/eval.c
160 */
161 /*
162 ** Structure used to accumulate the output
163 */
164 struct EvalResult {
165   char *z;               /* Accumulated output */
166   const char *zSep;      /* Separator */
167   int szSep;             /* Size of the separator string */
168   sqlite3_int64 nAlloc;  /* Number of bytes allocated for z[] */
169   sqlite3_int64 nUsed;   /* Number of bytes of z[] actually used */
170 };
171 
172 /*
173 ** Callback from sqlite_exec() for the eval() function.
174 */
175 static int callback(void *pCtx, int argc, char **argv, char **colnames){
176   struct EvalResult *p = (struct EvalResult*)pCtx;
177   int i;
178   for(i=0; i<argc; i++){
179     const char *z = argv[i] ? argv[i] : "";
180     size_t sz = strlen(z);
181     if( (sqlite3_int64)sz+p->nUsed+p->szSep+1 > p->nAlloc ){
182       char *zNew;
183       p->nAlloc = p->nAlloc*2 + sz + p->szSep + 1;
184       /* Using sqlite3_realloc64() would be better, but it is a recent
185       ** addition and will cause a segfault if loaded by an older version
186       ** of SQLite.  */
187       zNew = p->nAlloc<=0x7fffffff ? sqlite3_realloc(p->z, (int)p->nAlloc) : 0;
188       if( zNew==0 ){
189         sqlite3_free(p->z);
190         memset(p, 0, sizeof(*p));
191         return 1;
192       }
193       p->z = zNew;
194     }
195     if( p->nUsed>0 ){
196       memcpy(&p->z[p->nUsed], p->zSep, p->szSep);
197       p->nUsed += p->szSep;
198     }
199     memcpy(&p->z[p->nUsed], z, sz);
200     p->nUsed += sz;
201   }
202   return 0;
203 }
204 
205 /*
206 ** Implementation of the eval(X) and eval(X,Y) SQL functions.
207 **
208 ** Evaluate the SQL text in X.  Return the results, using string
209 ** Y as the separator.  If Y is omitted, use a single space character.
210 */
211 static void sqlEvalFunc(
212   sqlite3_context *context,
213   int argc,
214   sqlite3_value **argv
215 ){
216   const char *zSql;
217   sqlite3 *db;
218   char *zErr = 0;
219   int rc;
220   struct EvalResult x;
221 
222   memset(&x, 0, sizeof(x));
223   x.zSep = " ";
224   zSql = (const char*)sqlite3_value_text(argv[0]);
225   if( zSql==0 ) return;
226   if( argc>1 ){
227     x.zSep = (const char*)sqlite3_value_text(argv[1]);
228     if( x.zSep==0 ) return;
229   }
230   x.szSep = (int)strlen(x.zSep);
231   db = sqlite3_context_db_handle(context);
232   rc = sqlite3_exec(db, zSql, callback, &x, &zErr);
233   if( rc!=SQLITE_OK ){
234     sqlite3_result_error(context, zErr, -1);
235     sqlite3_free(zErr);
236   }else if( x.zSep==0 ){
237     sqlite3_result_error_nomem(context);
238     sqlite3_free(x.z);
239   }else{
240     sqlite3_result_text(context, x.z, (int)x.nUsed, sqlite3_free);
241   }
242 }
243 /* End of the eval() implementation
244 ******************************************************************************/
245 
246 /*
247 ** Print sketchy documentation for this utility program
248 */
249 static void showHelp(void){
250   printf("Usage: %s [options]\n", g.zArgv0);
251   printf(
252 "Read SQL text from standard input and evaluate it.\n"
253 "Options:\n"
254 "  --autovacuum          Enable AUTOVACUUM mode\n"
255 "  -f FILE               Read SQL text from FILE instead of standard input\n"
256 "  --heap SZ MIN         Memory allocator uses SZ bytes & min allocation MIN\n"
257 "  --help                Show this help text\n"
258 "  --initdb DBFILE       Initialize the in-memory database using template DBFILE\n"
259 "  --lookaside N SZ      Configure lookaside for N slots of SZ bytes each\n"
260 "  --pagesize N          Set the page size to N\n"
261 "  --pcache N SZ         Configure N pages of pagecache each of size SZ bytes\n"
262 "  -q                    Reduced output\n"
263 "  --quiet               Reduced output\n"
264 "  --scratch N SZ        Configure scratch memory for N slots of SZ bytes each\n"
265 "  --unique-cases FILE   Write all unique test cases to FILE\n"
266 "  --utf16be             Set text encoding to UTF-16BE\n"
267 "  --utf16le             Set text encoding to UTF-16LE\n"
268 "  -v                    Increased output\n"
269 "  --verbose             Increased output\n"
270   );
271 }
272 
273 /*
274 ** Return the value of a hexadecimal digit.  Return -1 if the input
275 ** is not a hex digit.
276 */
277 static int hexDigitValue(char c){
278   if( c>='0' && c<='9' ) return c - '0';
279   if( c>='a' && c<='f' ) return c - 'a' + 10;
280   if( c>='A' && c<='F' ) return c - 'A' + 10;
281   return -1;
282 }
283 
284 /*
285 ** Interpret zArg as an integer value, possibly with suffixes.
286 */
287 static int integerValue(const char *zArg){
288   sqlite3_int64 v = 0;
289   static const struct { char *zSuffix; int iMult; } aMult[] = {
290     { "KiB", 1024 },
291     { "MiB", 1024*1024 },
292     { "GiB", 1024*1024*1024 },
293     { "KB",  1000 },
294     { "MB",  1000000 },
295     { "GB",  1000000000 },
296     { "K",   1000 },
297     { "M",   1000000 },
298     { "G",   1000000000 },
299   };
300   int i;
301   int isNeg = 0;
302   if( zArg[0]=='-' ){
303     isNeg = 1;
304     zArg++;
305   }else if( zArg[0]=='+' ){
306     zArg++;
307   }
308   if( zArg[0]=='0' && zArg[1]=='x' ){
309     int x;
310     zArg += 2;
311     while( (x = hexDigitValue(zArg[0]))>=0 ){
312       v = (v<<4) + x;
313       zArg++;
314     }
315   }else{
316     while( isdigit(zArg[0]) ){
317       v = v*10 + zArg[0] - '0';
318       zArg++;
319     }
320   }
321   for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){
322     if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
323       v *= aMult[i].iMult;
324       break;
325     }
326   }
327   if( v>0x7fffffff ) abendError("parameter too large - max 2147483648");
328   return (int)(isNeg? -v : v);
329 }
330 
331 /*
332 ** Various operating modes
333 */
334 #define FZMODE_Generic   1
335 #define FZMODE_Strftime  2
336 #define FZMODE_Printf    3
337 #define FZMODE_Glob      4
338 
339 
340 int main(int argc, char **argv){
341   char *zIn = 0;          /* Input text */
342   int nAlloc = 0;         /* Number of bytes allocated for zIn[] */
343   int nIn = 0;            /* Number of bytes of zIn[] used */
344   size_t got;             /* Bytes read from input */
345   FILE *in = stdin;       /* Where to read SQL text from */
346   int rc = SQLITE_OK;     /* Result codes from API functions */
347   int i;                  /* Loop counter */
348   int iNext;              /* Next block of SQL */
349   sqlite3 *db;            /* Open database */
350   sqlite3 *dbInit = 0;    /* On-disk database used to initialize the in-memory db */
351   const char *zInitDb = 0;/* Name of the initialization database file */
352   char *zErrMsg = 0;      /* Error message returned from sqlite3_exec() */
353   const char *zEncoding = 0;    /* --utf16be or --utf16le */
354   int nHeap = 0, mnHeap = 0;    /* Heap size from --heap */
355   int nLook = 0, szLook = 0;    /* --lookaside configuration */
356   int nPCache = 0, szPCache = 0;/* --pcache configuration */
357   int nScratch = 0, szScratch=0;/* --scratch configuration */
358   int pageSize = 0;             /* Desired page size.  0 means default */
359   void *pHeap = 0;              /* Allocated heap space */
360   void *pLook = 0;              /* Allocated lookaside space */
361   void *pPCache = 0;            /* Allocated storage for pcache */
362   void *pScratch = 0;           /* Allocated storage for scratch */
363   int doAutovac = 0;            /* True for --autovacuum */
364   char *zSql;                   /* SQL to run */
365   char *zToFree = 0;            /* Call sqlite3_free() on this afte running zSql */
366   int iMode = FZMODE_Generic;   /* Operating mode */
367   const char *zCkGlob = 0;      /* Inputs must match this glob */
368   int verboseFlag = 0;          /* --verbose or -v flag */
369   int quietFlag = 0;            /* --quiet or -q flag */
370   int nTest = 0;                /* Number of test cases run */
371   int multiTest = 0;            /* True if there will be multiple test cases */
372   int lastPct = -1;             /* Previous percentage done output */
373   sqlite3 *dataDb = 0;          /* Database holding compacted input data */
374   sqlite3_stmt *pStmt = 0;      /* Statement to insert testcase into dataDb */
375   const char *zDataOut = 0;     /* Write compacted data to this output file */
376   int nHeader = 0;              /* Bytes of header comment text on input file */
377 
378 
379   g.zArgv0 = argv[0];
380   for(i=1; i<argc; i++){
381     const char *z = argv[i];
382     if( z[0]=='-' ){
383       z++;
384       if( z[0]=='-' ) z++;
385       if( strcmp(z,"autovacuum")==0 ){
386         doAutovac = 1;
387       }else
388       if( strcmp(z, "f")==0 && i+1<argc ){
389         if( in!=stdin ) abendError("only one -f allowed");
390         in = fopen(argv[++i],"rb");
391         if( in==0 )  abendError("cannot open input file \"%s\"", argv[i]);
392       }else
393       if( strcmp(z,"heap")==0 ){
394         if( i>=argc-2 ) abendError("missing arguments on %s\n", argv[i]);
395         nHeap = integerValue(argv[i+1]);
396         mnHeap = integerValue(argv[i+2]);
397         i += 2;
398       }else
399       if( strcmp(z,"help")==0 ){
400         showHelp();
401         return 0;
402       }else
403       if( strcmp(z, "initdb")==0 && i+1<argc ){
404         if( zInitDb!=0 ) abendError("only one --initdb allowed");
405         zInitDb = argv[++i];
406       }else
407       if( strcmp(z,"lookaside")==0 ){
408         if( i>=argc-2 ) abendError("missing arguments on %s", argv[i]);
409         nLook = integerValue(argv[i+1]);
410         szLook = integerValue(argv[i+2]);
411         i += 2;
412       }else
413       if( strcmp(z,"mode")==0 ){
414         if( i>=argc-1 ) abendError("missing argument on %s", argv[i]);
415         z = argv[++i];
416         if( strcmp(z,"generic")==0 ){
417           iMode = FZMODE_Printf;
418           zCkGlob = 0;
419         }else if( strcmp(z, "glob")==0 ){
420           iMode = FZMODE_Glob;
421           zCkGlob = "'*','*'";
422         }else if( strcmp(z, "printf")==0 ){
423           iMode = FZMODE_Printf;
424           zCkGlob = "'*',*";
425         }else if( strcmp(z, "strftime")==0 ){
426           iMode = FZMODE_Strftime;
427           zCkGlob = "'*',*";
428         }else{
429           abendError("unknown --mode: %s", z);
430         }
431       }else
432       if( strcmp(z,"pagesize")==0 ){
433         if( i>=argc-1 ) abendError("missing argument on %s", argv[i]);
434         pageSize = integerValue(argv[++i]);
435       }else
436       if( strcmp(z,"pcache")==0 ){
437         if( i>=argc-2 ) abendError("missing arguments on %s", argv[i]);
438         nPCache = integerValue(argv[i+1]);
439         szPCache = integerValue(argv[i+2]);
440         i += 2;
441       }else
442       if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
443         quietFlag = 1;
444         verboseFlag = 0;
445       }else
446       if( strcmp(z,"scratch")==0 ){
447         if( i>=argc-2 ) abendError("missing arguments on %s", argv[i]);
448         nScratch = integerValue(argv[i+1]);
449         szScratch = integerValue(argv[i+2]);
450         i += 2;
451       }else
452       if( strcmp(z, "unique-cases")==0 ){
453         if( i>=argc-1 ) abendError("missing arguments on %s", argv[i]);
454         if( zDataOut ) abendError("only one --minimize allowed");
455         zDataOut = argv[++i];
456       }else
457       if( strcmp(z,"utf16le")==0 ){
458         zEncoding = "utf16le";
459       }else
460       if( strcmp(z,"utf16be")==0 ){
461         zEncoding = "utf16be";
462       }else
463       if( strcmp(z,"verbose")==0 || strcmp(z,"v")==0 ){
464         quietFlag = 0;
465         verboseFlag = 1;
466       }else
467       {
468         abendError("unknown option: %s", argv[i]);
469       }
470     }else{
471       abendError("unknown argument: %s", argv[i]);
472     }
473   }
474   if( verboseFlag ) sqlite3_config(SQLITE_CONFIG_LOG, shellLog, 0);
475   if( nHeap>0 ){
476     pHeap = malloc( nHeap );
477     if( pHeap==0 ) fatalError("cannot allocate %d-byte heap\n", nHeap);
478     rc = sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap);
479     if( rc ) abendError("heap configuration failed: %d\n", rc);
480   }
481   if( nLook>0 ){
482     sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
483     if( szLook>0 ){
484       pLook = malloc( nLook*szLook );
485       if( pLook==0 ) fatalError("out of memory");
486     }
487   }
488   if( nScratch>0 && szScratch>0 ){
489     pScratch = malloc( nScratch*(sqlite3_int64)szScratch );
490     if( pScratch==0 ) fatalError("cannot allocate %lld-byte scratch",
491                                  nScratch*(sqlite3_int64)szScratch);
492     rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, pScratch, szScratch, nScratch);
493     if( rc ) abendError("scratch configuration failed: %d\n", rc);
494   }
495   if( nPCache>0 && szPCache>0 ){
496     pPCache = malloc( nPCache*(sqlite3_int64)szPCache );
497     if( pPCache==0 ) fatalError("cannot allocate %lld-byte pcache",
498                                  nPCache*(sqlite3_int64)szPCache);
499     rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache);
500     if( rc ) abendError("pcache configuration failed: %d", rc);
501   }
502   while( !feof(in) ){
503     nAlloc += nAlloc+1000;
504     zIn = realloc(zIn, nAlloc);
505     if( zIn==0 ) fatalError("out of memory");
506     got = fread(zIn+nIn, 1, nAlloc-nIn-1, in);
507     nIn += (int)got;
508     zIn[nIn] = 0;
509     if( got==0 ) break;
510   }
511   if( in!=stdin ) fclose(in);
512   if( zDataOut ){
513     rc = sqlite3_open(":memory:", &dataDb);
514     if( rc ) abendError("cannot open :memory: database");
515     rc = sqlite3_exec(dataDb,
516           "CREATE TABLE testcase(sql BLOB PRIMARY KEY) WITHOUT ROWID;",0,0,0);
517     if( rc ) abendError("%s", sqlite3_errmsg(dataDb));
518     rc = sqlite3_prepare_v2(dataDb, "INSERT OR IGNORE INTO testcase(sql)VALUES(?1)",
519                             -1, &pStmt, 0);
520     if( rc ) abendError("%s", sqlite3_errmsg(dataDb));
521   }
522   if( zInitDb ){
523     rc = sqlite3_open_v2(zInitDb, &dbInit, SQLITE_OPEN_READONLY, 0);
524     if( rc!=SQLITE_OK ){
525       abendError("unable to open initialization database \"%s\"", zInitDb);
526     }
527   }
528   for(i=0; i<nIn; i=iNext+1){   /* Skip initial lines beginning with '#' */
529     if( zIn[i]!='#' ) break;
530     for(iNext=i+1; iNext<nIn && zIn[iNext]!='\n'; iNext++){}
531   }
532   nHeader = i;
533   for(nTest=0; i<nIn; i=iNext, nTest++){
534     char cSaved;
535     if( strncmp(&zIn[i], "/****<",6)==0 ){
536       char *z = strstr(&zIn[i], ">****/");
537       if( z ){
538         z += 6;
539         if( verboseFlag ) printf("%.*s\n", (int)(z-&zIn[i]), &zIn[i]);
540         i += (int)(z-&zIn[i]);
541         multiTest = 1;
542       }
543     }
544     for(iNext=i; iNext<nIn && strncmp(&zIn[iNext],"/****<",6)!=0; iNext++){}
545     if( zDataOut ){
546       sqlite3_bind_blob(pStmt, 1, &zIn[i], iNext-i, SQLITE_STATIC);
547       rc = sqlite3_step(pStmt);
548       if( rc!=SQLITE_DONE ) abendError("%s", sqlite3_errmsg(dataDb));
549       sqlite3_reset(pStmt);
550       continue;
551     }
552     cSaved = zIn[iNext];
553     zIn[iNext] = 0;
554     if( zCkGlob && sqlite3_strglob(zCkGlob,&zIn[i])!=0 ){
555       zIn[iNext] = cSaved;
556       continue;
557     }
558     rc = sqlite3_open_v2(
559       "main.db", &db,
560       SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY,
561       0);
562     if( rc!=SQLITE_OK ){
563       abendError("Unable to open the in-memory database");
564     }
565     if( pLook ){
566       rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook, nLook);
567       if( rc!=SQLITE_OK ) abendError("lookaside configuration filed: %d", rc);
568     }
569     if( zInitDb ){
570       sqlite3_backup *pBackup;
571       pBackup = sqlite3_backup_init(db, "main", dbInit, "main");
572       rc = sqlite3_backup_step(pBackup, -1);
573       if( rc!=SQLITE_DONE ){
574         abendError("attempt to initialize the in-memory database failed (rc=%d)",
575                    rc);
576       }
577       sqlite3_backup_finish(pBackup);
578     }
579     if( verboseFlag ) sqlite3_trace(db, traceCallback, 0);
580     sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
581     sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
582     sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 1000000);
583     if( zEncoding ) sqlexec(db, "PRAGMA encoding=%s", zEncoding);
584     if( pageSize ) sqlexec(db, "PRAGMA pagesize=%d", pageSize);
585     if( doAutovac ) sqlexec(db, "PRAGMA auto_vacuum=FULL");
586     zSql = &zIn[i];
587     if( verboseFlag ){
588       printf("INPUT (offset: %d, size: %d): [%s]\n",
589               i, (int)strlen(&zIn[i]), &zIn[i]);
590     }else if( multiTest && !quietFlag ){
591       int pct = 10*iNext/nIn;
592       if( pct!=lastPct ){
593         if( lastPct<0 ) printf("fuzz test:");
594         printf(" %d%%", pct*10);
595         fflush(stdout);
596         lastPct = pct;
597       }
598     }
599     switch( iMode ){
600       case FZMODE_Glob:
601         zSql = zToFree = sqlite3_mprintf("SELECT glob(%s);", zSql);
602         break;
603       case FZMODE_Printf:
604         zSql = zToFree = sqlite3_mprintf("SELECT printf(%s);", zSql);
605         break;
606       case FZMODE_Strftime:
607         zSql = zToFree = sqlite3_mprintf("SELECT strftime(%s);", zSql);
608         break;
609     }
610     zErrMsg = 0;
611     rc = sqlite3_exec(db, zSql, verboseFlag ? execCallback : execNoop, 0, &zErrMsg);
612     if( zToFree ){
613       sqlite3_free(zToFree);
614       zToFree = 0;
615     }
616     zIn[iNext] = cSaved;
617     if( verboseFlag ){
618       printf("RESULT-CODE: %d\n", rc);
619       if( zErrMsg ){
620         printf("ERROR-MSG: [%s]\n", zErrMsg);
621       }
622     }
623     sqlite3_free(zErrMsg);
624     rc = sqlite3_close(db);
625     if( rc ){
626       abendError("sqlite3_close() failed with rc=%d", rc);
627     }
628     if( sqlite3_memory_used()>0 ){
629       abendError("memory in use after close: %lld bytes", sqlite3_memory_used());
630     }
631     if( nTest==1 ){
632       /* Simulate an error if the TEST_FAILURE environment variable is "5" */
633       char *zFailCode = getenv("TEST_FAILURE");
634       if( zFailCode ){
635         if( zFailCode[0]=='5' && zFailCode[1]==0 ){
636           abendError("simulated failure");
637         }else if( zFailCode[0]!=0 ){
638           /* If TEST_FAILURE is something other than 5, just exit the test
639           ** early */
640           printf("\nExit early due to TEST_FAILURE being set");
641           break;
642         }
643       }
644     }
645   }
646   if( !verboseFlag && multiTest && !quietFlag ) printf("\n");
647   if( nTest>1 && !quietFlag ){
648     printf("%d fuzz tests with no errors\nSQLite %s %s\n",
649            nTest, sqlite3_libversion(), sqlite3_sourceid());
650   }
651   if( zDataOut ){
652     int n = 0;
653     FILE *out = fopen(zDataOut, "wb");
654     if( out==0 ) abendError("cannot open %s for writing", zDataOut);
655     if( nHeader>0 ) fwrite(zIn, nHeader, 1, out);
656     sqlite3_finalize(pStmt);
657     rc = sqlite3_prepare_v2(dataDb, "SELECT sql FROM testcase", -1, &pStmt, 0);
658     if( rc ) abendError("%s", sqlite3_errmsg(dataDb));
659     while( sqlite3_step(pStmt)==SQLITE_ROW ){
660       fprintf(out,"/****<%d>****/", ++n);
661       fwrite(sqlite3_column_blob(pStmt,0),sqlite3_column_bytes(pStmt,0),1,out);
662     }
663     fclose(out);
664     sqlite3_finalize(pStmt);
665     sqlite3_close(dataDb);
666   }
667   free(zIn);
668   free(pHeap);
669   free(pLook);
670   free(pScratch);
671   free(pPCache);
672   return 0;
673 }
674