xref: /sqlite-3.40.0/tool/fuzzershell.c (revision 048810b6)
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   sqlite3_mem_methods sOrigMem;    /* Original memory methods */
76   sqlite3_mem_methods sOomMem;     /* Memory methods with OOM simulator */
77   int iOomCntdown;                 /* Memory fails on 1 to 0 transition */
78   int nOomFault;                   /* Increments for each OOM fault */
79   int bOomOnce;                    /* Fail just once if true */
80   int bOomEnable;                  /* True to enable OOM simulation */
81   int nOomBrkpt;                   /* Number of calls to oomFault() */
82 } g;
83 
84 /*
85 ** This routine is called when a simulated OOM occurs.  It exists as a
86 ** convenient place to set a debugger breakpoint.
87 */
88 static void oomFault(void){
89   g.nOomBrkpt++;
90 }
91 
92 
93 /* Versions of malloc() and realloc() that simulate OOM conditions */
94 static void *oomMalloc(int nByte){
95   if( nByte>0 && g.bOomEnable && g.iOomCntdown>0 ){
96     g.iOomCntdown--;
97     if( g.iOomCntdown==0 ){
98       if( g.nOomFault==0 ) oomFault();
99       g.nOomFault++;
100       if( !g.bOomOnce ) g.iOomCntdown = 1;
101       return 0;
102     }
103   }
104   return g.sOrigMem.xMalloc(nByte);
105 }
106 static void *oomRealloc(void *pOld, int nByte){
107   if( nByte>0 && g.bOomEnable && g.iOomCntdown>0 ){
108     g.iOomCntdown--;
109     if( g.iOomCntdown==0 ){
110       if( g.nOomFault==0 ) oomFault();
111       g.nOomFault++;
112       if( !g.bOomOnce ) g.iOomCntdown = 1;
113       return 0;
114     }
115   }
116   return g.sOrigMem.xRealloc(pOld, nByte);
117 }
118 
119 /*
120 ** Print an error message and abort in such a way to indicate to the
121 ** fuzzer that this counts as a crash.
122 */
123 static void abendError(const char *zFormat, ...){
124   va_list ap;
125   fprintf(stderr, "%s: ", g.zArgv0);
126   va_start(ap, zFormat);
127   vfprintf(stderr, zFormat, ap);
128   va_end(ap);
129   fprintf(stderr, "\n");
130   abort();
131 }
132 /*
133 ** Print an error message and quit, but not in a way that would look
134 ** like a crash.
135 */
136 static void fatalError(const char *zFormat, ...){
137   va_list ap;
138   fprintf(stderr, "%s: ", g.zArgv0);
139   va_start(ap, zFormat);
140   vfprintf(stderr, zFormat, ap);
141   va_end(ap);
142   fprintf(stderr, "\n");
143   exit(1);
144 }
145 
146 /*
147 ** Evaluate some SQL.  Abort if unable.
148 */
149 static void sqlexec(sqlite3 *db, const char *zFormat, ...){
150   va_list ap;
151   char *zSql;
152   char *zErrMsg = 0;
153   int rc;
154   va_start(ap, zFormat);
155   zSql = sqlite3_vmprintf(zFormat, ap);
156   va_end(ap);
157   rc = sqlite3_exec(db, zSql, 0, 0, &zErrMsg);
158   if( rc ) abendError("failed sql [%s]: %s", zSql, zErrMsg);
159   sqlite3_free(zSql);
160 }
161 
162 /*
163 ** This callback is invoked by sqlite3_log().
164 */
165 static void shellLog(void *pNotUsed, int iErrCode, const char *zMsg){
166   printf("LOG: (%d) %s\n", iErrCode, zMsg);
167 }
168 
169 /*
170 ** This callback is invoked by sqlite3_exec() to return query results.
171 */
172 static int execCallback(void *NotUsed, int argc, char **argv, char **colv){
173   int i;
174   static unsigned cnt = 0;
175   printf("ROW #%u:\n", ++cnt);
176   for(i=0; i<argc; i++){
177     printf(" %s=", colv[i]);
178     if( argv[i] ){
179       printf("[%s]\n", argv[i]);
180     }else{
181       printf("NULL\n");
182     }
183   }
184   return 0;
185 }
186 static int execNoop(void *NotUsed, int argc, char **argv, char **colv){
187   return 0;
188 }
189 
190 #ifndef SQLITE_OMIT_TRACE
191 /*
192 ** This callback is invoked by sqlite3_trace() as each SQL statement
193 ** starts.
194 */
195 static void traceCallback(void *NotUsed, const char *zMsg){
196   printf("TRACE: %s\n", zMsg);
197 }
198 #endif
199 
200 /***************************************************************************
201 ** eval() implementation copied from ../ext/misc/eval.c
202 */
203 /*
204 ** Structure used to accumulate the output
205 */
206 struct EvalResult {
207   char *z;               /* Accumulated output */
208   const char *zSep;      /* Separator */
209   int szSep;             /* Size of the separator string */
210   sqlite3_int64 nAlloc;  /* Number of bytes allocated for z[] */
211   sqlite3_int64 nUsed;   /* Number of bytes of z[] actually used */
212 };
213 
214 /*
215 ** Callback from sqlite_exec() for the eval() function.
216 */
217 static int callback(void *pCtx, int argc, char **argv, char **colnames){
218   struct EvalResult *p = (struct EvalResult*)pCtx;
219   int i;
220   for(i=0; i<argc; i++){
221     const char *z = argv[i] ? argv[i] : "";
222     size_t sz = strlen(z);
223     if( (sqlite3_int64)sz+p->nUsed+p->szSep+1 > p->nAlloc ){
224       char *zNew;
225       p->nAlloc = p->nAlloc*2 + sz + p->szSep + 1;
226       /* Using sqlite3_realloc64() would be better, but it is a recent
227       ** addition and will cause a segfault if loaded by an older version
228       ** of SQLite.  */
229       zNew = p->nAlloc<=0x7fffffff ? sqlite3_realloc(p->z, (int)p->nAlloc) : 0;
230       if( zNew==0 ){
231         sqlite3_free(p->z);
232         memset(p, 0, sizeof(*p));
233         return 1;
234       }
235       p->z = zNew;
236     }
237     if( p->nUsed>0 ){
238       memcpy(&p->z[p->nUsed], p->zSep, p->szSep);
239       p->nUsed += p->szSep;
240     }
241     memcpy(&p->z[p->nUsed], z, sz);
242     p->nUsed += sz;
243   }
244   return 0;
245 }
246 
247 /*
248 ** Implementation of the eval(X) and eval(X,Y) SQL functions.
249 **
250 ** Evaluate the SQL text in X.  Return the results, using string
251 ** Y as the separator.  If Y is omitted, use a single space character.
252 */
253 static void sqlEvalFunc(
254   sqlite3_context *context,
255   int argc,
256   sqlite3_value **argv
257 ){
258   const char *zSql;
259   sqlite3 *db;
260   char *zErr = 0;
261   int rc;
262   struct EvalResult x;
263 
264   memset(&x, 0, sizeof(x));
265   x.zSep = " ";
266   zSql = (const char*)sqlite3_value_text(argv[0]);
267   if( zSql==0 ) return;
268   if( argc>1 ){
269     x.zSep = (const char*)sqlite3_value_text(argv[1]);
270     if( x.zSep==0 ) return;
271   }
272   x.szSep = (int)strlen(x.zSep);
273   db = sqlite3_context_db_handle(context);
274   rc = sqlite3_exec(db, zSql, callback, &x, &zErr);
275   if( rc!=SQLITE_OK ){
276     sqlite3_result_error(context, zErr, -1);
277     sqlite3_free(zErr);
278   }else if( x.zSep==0 ){
279     sqlite3_result_error_nomem(context);
280     sqlite3_free(x.z);
281   }else{
282     sqlite3_result_text(context, x.z, (int)x.nUsed, sqlite3_free);
283   }
284 }
285 /* End of the eval() implementation
286 ******************************************************************************/
287 
288 /*
289 ** Print sketchy documentation for this utility program
290 */
291 static void showHelp(void){
292   printf("Usage: %s [options]\n", g.zArgv0);
293   printf(
294 "Read SQL text from standard input and evaluate it.\n"
295 "Options:\n"
296 "  --autovacuum          Enable AUTOVACUUM mode\n"
297 "  -f FILE               Read SQL text from FILE instead of standard input\n"
298 "  --heap SZ MIN         Memory allocator uses SZ bytes & min allocation MIN\n"
299 "  --help                Show this help text\n"
300 "  --initdb DBFILE       Initialize the in-memory database using template DBFILE\n"
301 "  --lookaside N SZ      Configure lookaside for N slots of SZ bytes each\n"
302 "  --oom                 Run each test multiple times in a simulated OOM loop\n"
303 "  --pagesize N          Set the page size to N\n"
304 "  --pcache N SZ         Configure N pages of pagecache each of size SZ bytes\n"
305 "  -q                    Reduced output\n"
306 "  --quiet               Reduced output\n"
307 "  --scratch N SZ        Configure scratch memory for N slots of SZ bytes each\n"
308 "  --unique-cases FILE   Write all unique test cases to FILE\n"
309 "  --utf16be             Set text encoding to UTF-16BE\n"
310 "  --utf16le             Set text encoding to UTF-16LE\n"
311 "  -v                    Increased output\n"
312 "  --verbose             Increased output\n"
313   );
314 }
315 
316 /*
317 ** Return the value of a hexadecimal digit.  Return -1 if the input
318 ** is not a hex digit.
319 */
320 static int hexDigitValue(char c){
321   if( c>='0' && c<='9' ) return c - '0';
322   if( c>='a' && c<='f' ) return c - 'a' + 10;
323   if( c>='A' && c<='F' ) return c - 'A' + 10;
324   return -1;
325 }
326 
327 /*
328 ** Interpret zArg as an integer value, possibly with suffixes.
329 */
330 static int integerValue(const char *zArg){
331   sqlite3_int64 v = 0;
332   static const struct { char *zSuffix; int iMult; } aMult[] = {
333     { "KiB", 1024 },
334     { "MiB", 1024*1024 },
335     { "GiB", 1024*1024*1024 },
336     { "KB",  1000 },
337     { "MB",  1000000 },
338     { "GB",  1000000000 },
339     { "K",   1000 },
340     { "M",   1000000 },
341     { "G",   1000000000 },
342   };
343   int i;
344   int isNeg = 0;
345   if( zArg[0]=='-' ){
346     isNeg = 1;
347     zArg++;
348   }else if( zArg[0]=='+' ){
349     zArg++;
350   }
351   if( zArg[0]=='0' && zArg[1]=='x' ){
352     int x;
353     zArg += 2;
354     while( (x = hexDigitValue(zArg[0]))>=0 ){
355       v = (v<<4) + x;
356       zArg++;
357     }
358   }else{
359     while( isdigit(zArg[0]) ){
360       v = v*10 + zArg[0] - '0';
361       zArg++;
362     }
363   }
364   for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){
365     if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
366       v *= aMult[i].iMult;
367       break;
368     }
369   }
370   if( v>0x7fffffff ) abendError("parameter too large - max 2147483648");
371   return (int)(isNeg? -v : v);
372 }
373 
374 /*
375 ** Various operating modes
376 */
377 #define FZMODE_Generic   1
378 #define FZMODE_Strftime  2
379 #define FZMODE_Printf    3
380 #define FZMODE_Glob      4
381 
382 
383 int main(int argc, char **argv){
384   char *zIn = 0;          /* Input text */
385   int nAlloc = 0;         /* Number of bytes allocated for zIn[] */
386   int nIn = 0;            /* Number of bytes of zIn[] used */
387   size_t got;             /* Bytes read from input */
388   FILE *in = stdin;       /* Where to read SQL text from */
389   int rc = SQLITE_OK;     /* Result codes from API functions */
390   int i;                  /* Loop counter */
391   int iNext;              /* Next block of SQL */
392   sqlite3 *db;            /* Open database */
393   sqlite3 *dbInit = 0;    /* On-disk database used to initialize the in-memory db */
394   const char *zInitDb = 0;/* Name of the initialization database file */
395   char *zErrMsg = 0;      /* Error message returned from sqlite3_exec() */
396   const char *zEncoding = 0;    /* --utf16be or --utf16le */
397   int nHeap = 0, mnHeap = 0;    /* Heap size from --heap */
398   int nLook = 0, szLook = 0;    /* --lookaside configuration */
399   int nPCache = 0, szPCache = 0;/* --pcache configuration */
400   int nScratch = 0, szScratch=0;/* --scratch configuration */
401   int pageSize = 0;             /* Desired page size.  0 means default */
402   void *pHeap = 0;              /* Allocated heap space */
403   void *pLook = 0;              /* Allocated lookaside space */
404   void *pPCache = 0;            /* Allocated storage for pcache */
405   void *pScratch = 0;           /* Allocated storage for scratch */
406   int doAutovac = 0;            /* True for --autovacuum */
407   char *zSql;                   /* SQL to run */
408   char *zToFree = 0;            /* Call sqlite3_free() on this afte running zSql */
409   int iMode = FZMODE_Generic;   /* Operating mode */
410   const char *zCkGlob = 0;      /* Inputs must match this glob */
411   int verboseFlag = 0;          /* --verbose or -v flag */
412   int quietFlag = 0;            /* --quiet or -q flag */
413   int nTest = 0;                /* Number of test cases run */
414   int multiTest = 0;            /* True if there will be multiple test cases */
415   int lastPct = -1;             /* Previous percentage done output */
416   sqlite3 *dataDb = 0;          /* Database holding compacted input data */
417   sqlite3_stmt *pStmt = 0;      /* Statement to insert testcase into dataDb */
418   const char *zDataOut = 0;     /* Write compacted data to this output file */
419   int nHeader = 0;              /* Bytes of header comment text on input file */
420   int oomFlag = 0;              /* --oom */
421   int oomCnt = 0;               /* Counter for the OOM loop */
422   char zErrBuf[200];            /* Space for the error message */
423   const char *zFailCode;        /* Value of the TEST_FAILURE environment var */
424 
425 
426   zFailCode = getenv("TEST_FAILURE");
427   g.zArgv0 = argv[0];
428   for(i=1; i<argc; i++){
429     const char *z = argv[i];
430     if( z[0]=='-' ){
431       z++;
432       if( z[0]=='-' ) z++;
433       if( strcmp(z,"autovacuum")==0 ){
434         doAutovac = 1;
435       }else
436       if( strcmp(z, "f")==0 && i+1<argc ){
437         if( in!=stdin ) abendError("only one -f allowed");
438         in = fopen(argv[++i],"rb");
439         if( in==0 )  abendError("cannot open input file \"%s\"", argv[i]);
440       }else
441       if( strcmp(z,"heap")==0 ){
442         if( i>=argc-2 ) abendError("missing arguments on %s\n", argv[i]);
443         nHeap = integerValue(argv[i+1]);
444         mnHeap = integerValue(argv[i+2]);
445         i += 2;
446       }else
447       if( strcmp(z,"help")==0 ){
448         showHelp();
449         return 0;
450       }else
451       if( strcmp(z, "initdb")==0 && i+1<argc ){
452         if( zInitDb!=0 ) abendError("only one --initdb allowed");
453         zInitDb = argv[++i];
454       }else
455       if( strcmp(z,"lookaside")==0 ){
456         if( i>=argc-2 ) abendError("missing arguments on %s", argv[i]);
457         nLook = integerValue(argv[i+1]);
458         szLook = integerValue(argv[i+2]);
459         i += 2;
460       }else
461       if( strcmp(z,"mode")==0 ){
462         if( i>=argc-1 ) abendError("missing argument on %s", argv[i]);
463         z = argv[++i];
464         if( strcmp(z,"generic")==0 ){
465           iMode = FZMODE_Printf;
466           zCkGlob = 0;
467         }else if( strcmp(z, "glob")==0 ){
468           iMode = FZMODE_Glob;
469           zCkGlob = "'*','*'";
470         }else if( strcmp(z, "printf")==0 ){
471           iMode = FZMODE_Printf;
472           zCkGlob = "'*',*";
473         }else if( strcmp(z, "strftime")==0 ){
474           iMode = FZMODE_Strftime;
475           zCkGlob = "'*',*";
476         }else{
477           abendError("unknown --mode: %s", z);
478         }
479       }else
480       if( strcmp(z,"oom")==0 ){
481         oomFlag = 1;
482       }else
483       if( strcmp(z,"pagesize")==0 ){
484         if( i>=argc-1 ) abendError("missing argument on %s", argv[i]);
485         pageSize = integerValue(argv[++i]);
486       }else
487       if( strcmp(z,"pcache")==0 ){
488         if( i>=argc-2 ) abendError("missing arguments on %s", argv[i]);
489         nPCache = integerValue(argv[i+1]);
490         szPCache = integerValue(argv[i+2]);
491         i += 2;
492       }else
493       if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
494         quietFlag = 1;
495         verboseFlag = 0;
496       }else
497       if( strcmp(z,"scratch")==0 ){
498         if( i>=argc-2 ) abendError("missing arguments on %s", argv[i]);
499         nScratch = integerValue(argv[i+1]);
500         szScratch = integerValue(argv[i+2]);
501         i += 2;
502       }else
503       if( strcmp(z, "unique-cases")==0 ){
504         if( i>=argc-1 ) abendError("missing arguments on %s", argv[i]);
505         if( zDataOut ) abendError("only one --minimize allowed");
506         zDataOut = argv[++i];
507       }else
508       if( strcmp(z,"utf16le")==0 ){
509         zEncoding = "utf16le";
510       }else
511       if( strcmp(z,"utf16be")==0 ){
512         zEncoding = "utf16be";
513       }else
514       if( strcmp(z,"verbose")==0 || strcmp(z,"v")==0 ){
515         quietFlag = 0;
516         verboseFlag = 1;
517       }else
518       {
519         abendError("unknown option: %s", argv[i]);
520       }
521     }else{
522       abendError("unknown argument: %s", argv[i]);
523     }
524   }
525   if( verboseFlag ) sqlite3_config(SQLITE_CONFIG_LOG, shellLog, 0);
526   if( nHeap>0 ){
527     pHeap = malloc( nHeap );
528     if( pHeap==0 ) fatalError("cannot allocate %d-byte heap\n", nHeap);
529     rc = sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap);
530     if( rc ) abendError("heap configuration failed: %d\n", rc);
531   }
532   if( oomFlag ){
533     sqlite3_config(SQLITE_CONFIG_GETMALLOC, &g.sOrigMem);
534     g.sOomMem = g.sOrigMem;
535     g.sOomMem.xMalloc = oomMalloc;
536     g.sOomMem.xRealloc = oomRealloc;
537     sqlite3_config(SQLITE_CONFIG_MALLOC, &g.sOomMem);
538   }
539   if( nLook>0 ){
540     sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
541     if( szLook>0 ){
542       pLook = malloc( nLook*szLook );
543       if( pLook==0 ) fatalError("out of memory");
544     }
545   }
546   if( nScratch>0 && szScratch>0 ){
547     pScratch = malloc( nScratch*(sqlite3_int64)szScratch );
548     if( pScratch==0 ) fatalError("cannot allocate %lld-byte scratch",
549                                  nScratch*(sqlite3_int64)szScratch);
550     rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, pScratch, szScratch, nScratch);
551     if( rc ) abendError("scratch configuration failed: %d\n", rc);
552   }
553   if( nPCache>0 && szPCache>0 ){
554     pPCache = malloc( nPCache*(sqlite3_int64)szPCache );
555     if( pPCache==0 ) fatalError("cannot allocate %lld-byte pcache",
556                                  nPCache*(sqlite3_int64)szPCache);
557     rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache);
558     if( rc ) abendError("pcache configuration failed: %d", rc);
559   }
560   while( !feof(in) ){
561     nAlloc += nAlloc+1000;
562     zIn = realloc(zIn, nAlloc);
563     if( zIn==0 ) fatalError("out of memory");
564     got = fread(zIn+nIn, 1, nAlloc-nIn-1, in);
565     nIn += (int)got;
566     zIn[nIn] = 0;
567     if( got==0 ) break;
568   }
569   if( in!=stdin ) fclose(in);
570   if( zDataOut ){
571     rc = sqlite3_open(":memory:", &dataDb);
572     if( rc ) abendError("cannot open :memory: database");
573     rc = sqlite3_exec(dataDb,
574           "CREATE TABLE testcase(sql BLOB PRIMARY KEY) WITHOUT ROWID;",0,0,0);
575     if( rc ) abendError("%s", sqlite3_errmsg(dataDb));
576     rc = sqlite3_prepare_v2(dataDb, "INSERT OR IGNORE INTO testcase(sql)VALUES(?1)",
577                             -1, &pStmt, 0);
578     if( rc ) abendError("%s", sqlite3_errmsg(dataDb));
579   }
580   if( zInitDb ){
581     rc = sqlite3_open_v2(zInitDb, &dbInit, SQLITE_OPEN_READONLY, 0);
582     if( rc!=SQLITE_OK ){
583       abendError("unable to open initialization database \"%s\"", zInitDb);
584     }
585   }
586   for(i=0; i<nIn; i=iNext+1){   /* Skip initial lines beginning with '#' */
587     if( zIn[i]!='#' ) break;
588     for(iNext=i+1; iNext<nIn && zIn[iNext]!='\n'; iNext++){}
589   }
590   nHeader = i;
591   for(nTest=0; i<nIn; i=iNext, nTest++){
592     char cSaved;
593     if( strncmp(&zIn[i], "/****<",6)==0 ){
594       char *z = strstr(&zIn[i], ">****/");
595       if( z ){
596         z += 6;
597         if( verboseFlag ) printf("%.*s\n", (int)(z-&zIn[i]), &zIn[i]);
598         i += (int)(z-&zIn[i]);
599         multiTest = 1;
600       }
601     }
602     for(iNext=i; iNext<nIn && strncmp(&zIn[iNext],"/****<",6)!=0; iNext++){}
603     if( zDataOut ){
604       sqlite3_bind_blob(pStmt, 1, &zIn[i], iNext-i, SQLITE_STATIC);
605       rc = sqlite3_step(pStmt);
606       if( rc!=SQLITE_DONE ) abendError("%s", sqlite3_errmsg(dataDb));
607       sqlite3_reset(pStmt);
608       continue;
609     }
610     cSaved = zIn[iNext];
611     zIn[iNext] = 0;
612     if( zCkGlob && sqlite3_strglob(zCkGlob,&zIn[i])!=0 ){
613       zIn[iNext] = cSaved;
614       continue;
615     }
616     zSql = &zIn[i];
617     if( verboseFlag ){
618       printf("INPUT (offset: %d, size: %d): [%s]\n",
619               i, (int)strlen(&zIn[i]), &zIn[i]);
620     }else if( multiTest && !quietFlag ){
621       int pct = oomFlag ? 100*iNext/nIn : ((10*iNext)/nIn)*10;
622       if( pct!=lastPct ){
623         if( lastPct<0 ) printf("fuzz test:");
624         printf(" %d%%", pct);
625         fflush(stdout);
626         lastPct = pct;
627       }
628     }
629     switch( iMode ){
630       case FZMODE_Glob:
631         zSql = zToFree = sqlite3_mprintf("SELECT glob(%s);", zSql);
632         break;
633       case FZMODE_Printf:
634         zSql = zToFree = sqlite3_mprintf("SELECT printf(%s);", zSql);
635         break;
636       case FZMODE_Strftime:
637         zSql = zToFree = sqlite3_mprintf("SELECT strftime(%s);", zSql);
638         break;
639     }
640     if( oomFlag ){
641       oomCnt = g.iOomCntdown = 1;
642       g.nOomFault = 0;
643       g.bOomOnce = 1;
644       if( verboseFlag ) printf("Once.%d\n", oomCnt);
645     }else{
646       oomCnt = 0;
647     }
648     do{
649       rc = sqlite3_open_v2(
650         "main.db", &db,
651         SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY,
652         0);
653       if( rc!=SQLITE_OK ){
654         abendError("Unable to open the in-memory database");
655       }
656       if( pLook ){
657         rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook, nLook);
658         if( rc!=SQLITE_OK ) abendError("lookaside configuration filed: %d", rc);
659       }
660       if( zInitDb ){
661         sqlite3_backup *pBackup;
662         pBackup = sqlite3_backup_init(db, "main", dbInit, "main");
663         rc = sqlite3_backup_step(pBackup, -1);
664         if( rc!=SQLITE_DONE ){
665           abendError("attempt to initialize the in-memory database failed (rc=%d)",
666                      rc);
667         }
668         sqlite3_backup_finish(pBackup);
669       }
670   #ifndef SQLITE_OMIT_TRACE
671       if( verboseFlag ) sqlite3_trace(db, traceCallback, 0);
672   #endif
673       sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
674       sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
675       sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 1000000);
676       if( zEncoding ) sqlexec(db, "PRAGMA encoding=%s", zEncoding);
677       if( pageSize ) sqlexec(db, "PRAGMA pagesize=%d", pageSize);
678       if( doAutovac ) sqlexec(db, "PRAGMA auto_vacuum=FULL");
679       g.bOomEnable = 1;
680       if( verboseFlag ){
681         zErrMsg = 0;
682         rc = sqlite3_exec(db, zSql, execCallback, 0, &zErrMsg);
683         if( zErrMsg ){
684           sqlite3_snprintf(sizeof(zErrBuf),zErrBuf,"%z", zErrMsg);
685           zErrMsg = 0;
686         }
687       }else {
688         rc = sqlite3_exec(db, zSql, execNoop, 0, 0);
689       }
690       g.bOomEnable = 0;
691       rc = sqlite3_close(db);
692       if( rc ){
693         abendError("sqlite3_close() failed with rc=%d", rc);
694       }
695       if( sqlite3_memory_used()>0 ){
696         abendError("memory in use after close: %lld bytes", sqlite3_memory_used());
697       }
698       if( oomFlag ){
699         if( g.nOomFault==0 || oomCnt>2000 ){
700           if( g.bOomOnce ){
701             oomCnt = g.iOomCntdown = 1;
702             g.bOomOnce = 0;
703           }else{
704             oomCnt = 0;
705           }
706         }else{
707           g.iOomCntdown = ++oomCnt;
708           g.nOomFault = 0;
709         }
710         if( oomCnt ){
711           if( verboseFlag ){
712             printf("%s.%d\n", g.bOomOnce ? "Once" : "Multi", oomCnt);
713           }
714           nTest++;
715         }
716       }
717     }while( oomCnt>0 );
718     if( zToFree ){
719       sqlite3_free(zToFree);
720       zToFree = 0;
721     }
722     zIn[iNext] = cSaved;
723     if( verboseFlag ){
724       printf("RESULT-CODE: %d\n", rc);
725       if( zErrMsg ){
726         printf("ERROR-MSG: [%s]\n", zErrBuf);
727       }
728     }
729     /* Simulate an error if the TEST_FAILURE environment variable is "5" */
730     if( zFailCode ){
731       if( zFailCode[0]=='5' && zFailCode[1]==0 ){
732         abendError("simulated failure");
733       }else if( zFailCode[0]!=0 ){
734         /* If TEST_FAILURE is something other than 5, just exit the test
735         ** early */
736         printf("\nExit early due to TEST_FAILURE being set");
737         break;
738       }
739     }
740   }
741   if( !verboseFlag && multiTest && !quietFlag ) printf("\n");
742   if( nTest>1 && !quietFlag ){
743     printf("%d fuzz tests with no errors\nSQLite %s %s\n",
744            nTest, sqlite3_libversion(), sqlite3_sourceid());
745   }
746   if( zDataOut ){
747     int n = 0;
748     FILE *out = fopen(zDataOut, "wb");
749     if( out==0 ) abendError("cannot open %s for writing", zDataOut);
750     if( nHeader>0 ) fwrite(zIn, nHeader, 1, out);
751     sqlite3_finalize(pStmt);
752     rc = sqlite3_prepare_v2(dataDb, "SELECT sql FROM testcase", -1, &pStmt, 0);
753     if( rc ) abendError("%s", sqlite3_errmsg(dataDb));
754     while( sqlite3_step(pStmt)==SQLITE_ROW ){
755       fprintf(out,"/****<%d>****/", ++n);
756       fwrite(sqlite3_column_blob(pStmt,0),sqlite3_column_bytes(pStmt,0),1,out);
757     }
758     fclose(out);
759     sqlite3_finalize(pStmt);
760     sqlite3_close(dataDb);
761   }
762   free(zIn);
763   free(pHeap);
764   free(pLook);
765   free(pScratch);
766   free(pPCache);
767   return 0;
768 }
769