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