/ Check-in [e2991a7e]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Extend fuzzcheck so that it can process dbsqlfuzz cases. Add a collection of interesting dbsqlfuzz cases to the standard test suite.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: e2991a7ecf5dd241c4bab7c7cadc4901043fb0c3ea1fac70b684f6d8332677f1
User & Date: drh 2019-01-25 14:23:36
Context
2019-01-25
14:48
Add an assert_fts3_nc() macro to fts3 - for assert() conditions that are only true when it is guaranteed that the fts3 database is not corrupt. check-in: 3498908c user: dan tags: trunk
14:23
Extend fuzzcheck so that it can process dbsqlfuzz cases. Add a collection of interesting dbsqlfuzz cases to the standard test suite. check-in: e2991a7e user: drh tags: trunk
14:16
Fix the xFetch method of the "memdb" VFS (used by deserialize) so that it is robust against corrupt database file. Closed-Leaf check-in: 2c1ef40e user: drh tags: dbsqlfuzz-in-fuzzcheck
13:42
Fix a couple of assert() statments in btree.c that could fail with corrupt databases. check-in: 5eb5e828 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   585    585   FUZZDATA = \
   586    586     $(TOP)/test/fuzzdata1.db \
   587    587     $(TOP)/test/fuzzdata2.db \
   588    588     $(TOP)/test/fuzzdata3.db \
   589    589     $(TOP)/test/fuzzdata4.db \
   590    590     $(TOP)/test/fuzzdata5.db \
   591    591     $(TOP)/test/fuzzdata6.db \
   592         -  $(TOP)/test/fuzzdata7.db
          592  +  $(TOP)/test/fuzzdata7.db \
          593  +  $(TOP)/test/fuzzdata8.db
   593    594   
   594    595   # Standard options to testfixture
   595    596   #
   596    597   TESTOPTS = --verbose=file --output=test-out.txt
   597    598   
   598    599   # Extra compiler options for various shell tools
   599    600   #
................................................................................
   608    609   SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
   609    610   SHELL_OPT += -DSQLITE_ENABLE_DESERIALIZE
   610    611   SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
   611    612   FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
   612    613   FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
   613    614   FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
   614    615   FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
          616  +FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
          617  +FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
          618  +#FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS5
          619  +FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE
          620  +FUZZCHECK_OPT += -DSQLITE_ENABLE_GEOPOLY
          621  +FUZZCHECK_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
   615    622   FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
   616    623   DBFUZZ_OPT =
   617    624   
   618    625   # This is the default Makefile target.  The objects listed here
   619    626   # are what get build when you type just "make" with no arguments.
   620    627   #
   621    628   all:	sqlite3.h libsqlite3.la sqlite3$(TEXE) $(HAVE_TCL:1=libtclsqlite3.la)

Changes to Makefile.msc.

  1622   1622   FUZZDATA = \
  1623   1623     $(TOP)\test\fuzzdata1.db \
  1624   1624     $(TOP)\test\fuzzdata2.db \
  1625   1625     $(TOP)\test\fuzzdata3.db \
  1626   1626     $(TOP)\test\fuzzdata4.db \
  1627   1627     $(TOP)\test\fuzzdata5.db \
  1628   1628     $(TOP)\test\fuzzdata6.db \
  1629         -  $(TOP)\test\fuzzdata7.db
         1629  +  $(TOP)\test\fuzzdata7.db \
         1630  +  $(TOP)\test\fuzzdata8.db
  1630   1631   # <</mark>>
  1631   1632   
  1632   1633   # Additional compiler options for the shell.  These are only effective
  1633   1634   # when the shell is not being dynamically linked.
  1634   1635   #
  1635   1636   !IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
  1636   1637   SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
................................................................................
  1640   1641   !ENDIF
  1641   1642   
  1642   1643   # <<mark>>
  1643   1644   # Extra compiler options for various test tools.
  1644   1645   #
  1645   1646   MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
  1646   1647   FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
  1647         -FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
         1648  +FUZZCHECK_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
         1649  +FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DESERIALIZE
         1650  +FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_FTS4
         1651  +FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_RTREE
         1652  +FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_GEOPOLY
         1653  +FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DBSTAT_VTAB
         1654  +
  1648   1655   FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c
  1649   1656   OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
  1650   1657   DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
  1651   1658   KV_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
  1652   1659   ST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0
  1653   1660   
  1654   1661   # Standard options to testfixture.
................................................................................
  1727   1734   fuzzershell.exe:	$(TOP)\tool\fuzzershell.c $(SQLITE3C) $(SQLITE3H)
  1728   1735   	$(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) $(TOP)\tool\fuzzershell.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1729   1736   
  1730   1737   dbfuzz.exe:	$(TOP)\test\dbfuzz.c $(SQLITE3C) $(SQLITE3H)
  1731   1738   	$(LTLINK) $(NO_WARN) $(DBFUZZ_COMPILE_OPTS) $(TOP)\test\dbfuzz.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1732   1739   
  1733   1740   fuzzcheck.exe:	$(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H)
  1734         -	$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
         1741  +	$(LTLINK) $(NO_WARN) $(FUZZCHECK_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1735   1742   
  1736   1743   ossshell.exe:	$(OSSSHELL_SRC) $(SQLITE3C) $(SQLITE3H)
  1737         -	$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
         1744  +	$(LTLINK) $(NO_WARN) $(FUZZCHECK_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1738   1745   
  1739   1746   sessionfuzz.exe:	zlib $(TOP)\test\sessionfuzz.c $(SQLITE3C) $(SQLITE3H)
  1740   1747   	$(LTLINK) $(NO_WARN) -I$(ZLIBINCDIR) $(TOP)\test\sessionfuzz.c /link $(LDFLAGS) $(LTLINKOPTS) /LIBPATH:$(ZLIBLIBDIR) $(ZLIBLIB)
  1741   1748   
  1742   1749   mptester.exe:	$(TOP)\mptest\mptest.c $(SQLITE3C) $(SQLITE3H)
  1743   1750   	$(LTLINK) $(NO_WARN) $(MPTESTER_COMPILE_OPTS) $(TOP)\mptest\mptest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1744   1751   

Changes to main.mk.

   506    506   FUZZDATA = \
   507    507     $(TOP)/test/fuzzdata1.db \
   508    508     $(TOP)/test/fuzzdata2.db \
   509    509     $(TOP)/test/fuzzdata3.db \
   510    510     $(TOP)/test/fuzzdata4.db \
   511    511     $(TOP)/test/fuzzdata5.db \
   512    512     $(TOP)/test/fuzzdata6.db \
   513         -  $(TOP)/test/fuzzdata7.db
          513  +  $(TOP)/test/fuzzdata7.db \
          514  +  $(TOP)/test/fuzzdata8.db
   514    515   
   515    516   # Standard options to testfixture
   516    517   #
   517    518   TESTOPTS = --verbose=file --output=test-out.txt
   518    519   
   519    520   # Extra compiler options for various shell tools
   520    521   #
................................................................................
   527    528   SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
   528    529   SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
   529    530   SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
   530    531   FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
   531    532   FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
   532    533   FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
   533    534   FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
          535  +FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
          536  +FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
          537  +FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE
          538  +FUZZCHECK_OPT += -DSQLITE_ENABLE_GEOPOLY
          539  +FUZZCHECK_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
   534    540   DBFUZZ_OPT =
   535    541   KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
   536    542   ST_OPT = -DSQLITE_THREADSAFE=0
   537    543   
   538    544   # This is the default Makefile target.  The objects listed here
   539    545   # are what get build when you type just "make" with no arguments.
   540    546   #

Changes to src/memdb.c.

   306    306   static int memdbFetch(
   307    307     sqlite3_file *pFile,
   308    308     sqlite3_int64 iOfst,
   309    309     int iAmt,
   310    310     void **pp
   311    311   ){
   312    312     MemFile *p = (MemFile *)pFile;
   313         -  p->nMmap++;
   314         -  *pp = (void*)(p->aData + iOfst);
          313  +  if( iOfst+iAmt>p->sz ){
          314  +    assert( CORRUPT_DB );
          315  +    *pp = 0;
          316  +  }else{
          317  +    p->nMmap++;
          318  +    *pp = (void*)(p->aData + iOfst);
          319  +  }
   315    320     return SQLITE_OK;
   316    321   }
   317    322   
   318    323   /* Release a memory-mapped page */
   319    324   static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
   320    325     MemFile *p = (MemFile *)pFile;
   321    326     p->nMmap--;

Changes to test/fuzzcheck.c.

    65     65   ** DB values that were running when the crash occurred.
    66     66   */
    67     67   #include <stdio.h>
    68     68   #include <stdlib.h>
    69     69   #include <string.h>
    70     70   #include <stdarg.h>
    71     71   #include <ctype.h>
           72  +#include <assert.h>
    72     73   #include "sqlite3.h"
    73     74   #define ISSPACE(X) isspace((unsigned char)(X))
    74     75   #define ISDIGIT(X) isdigit((unsigned char)(X))
    75     76   
    76     77   
    77     78   #ifdef __unix__
    78     79   # include <signal.h>
................................................................................
   396    397     while( p ){
   397    398       pNext = p->pNext;
   398    399       free(p);
   399    400       p = pNext;
   400    401     }
   401    402   }
   402    403   
   403         -
   404    404   /* Return the current wall-clock time */
   405    405   static sqlite3_int64 timeOfDay(void){
   406    406     static sqlite3_vfs *clockVfs = 0;
   407    407     sqlite3_int64 t;
   408    408     if( clockVfs==0 ){
   409    409       clockVfs = sqlite3_vfs_find(0);
   410    410       if( clockVfs==0 ) return 0;
................................................................................
   414    414     }else{
   415    415       double r;
   416    416       clockVfs->xCurrentTime(clockVfs, &r);
   417    417       t = (sqlite3_int64)(r*86400000.0);
   418    418     }
   419    419     return t;
   420    420   }
          421  +
          422  +/***************************************************************************
          423  +** Code to process combined database+SQL scripts generated by the
          424  +** dbsqlfuzz fuzzer.
          425  +*/
          426  +
          427  +/* An instance of the following object is passed by pointer as the
          428  +** client data to various callbacks.
          429  +*/
          430  +typedef struct FuzzCtx {
          431  +  sqlite3 *db;               /* The database connection */
          432  +  sqlite3_int64 iCutoffTime; /* Stop processing at this time. */
          433  +  sqlite3_int64 iLastCb;     /* Time recorded for previous progress callback */
          434  +  sqlite3_int64 mxInterval;  /* Longest interval between two progress calls */
          435  +  unsigned nCb;              /* Number of progress callbacks */
          436  +  unsigned mxCb;             /* Maximum number of progress callbacks allowed */
          437  +  unsigned execCnt;          /* Number of calls to the sqlite3_exec callback */
          438  +  int timeoutHit;            /* True when reaching a timeout */
          439  +} FuzzCtx;
          440  +
          441  +/* Verbosity level for the dbsqlfuzz test runner */
          442  +static int eVerbosity = 0;
          443  +
          444  +/* True to activate PRAGMA vdbe_debug=on */
          445  +static int bVdbeDebug = 0;
          446  +
          447  +/* Timeout for each fuzzing attempt, in milliseconds */
          448  +static int iTimeout = 10000;   /* Defaults to 10 seconds */
          449  +
          450  +/* Maximum number of progress handler callbacks */
          451  +static unsigned int mxProgressCb = 2000;
          452  +
          453  +/* Maximum string length in SQLite */
          454  +static int lengthLimit = 1000000;
          455  +
          456  +/* Maximum byte-code program length in SQLite */
          457  +static int vdbeOpLimit = 25000;
          458  +
          459  +/* Maximum size of the in-memory database */
          460  +static sqlite3_int64 maxDbSize = 104857600;
          461  +
          462  +/*
          463  +** Translate a single byte of Hex into an integer.
          464  +** This routine only works if h really is a valid hexadecimal
          465  +** character:  0..9a..fA..F
          466  +*/
          467  +static unsigned int hexToInt(unsigned int h){
          468  +#ifdef SQLITE_EBCDIC
          469  +  h += 9*(1&~(h>>4));   /* EBCDIC */
          470  +#else
          471  +  h += 9*(1&(h>>6));    /* ASCII */
          472  +#endif
          473  +  return h & 0xf;
          474  +}
          475  +
          476  +/*
          477  +** The first character of buffer zIn[0..nIn-1] is a '['.  This routine
          478  +** checked to see if the buffer holds "[NNNN]" or "[+NNNN]" and if it
          479  +** does it makes corresponding changes to the *pK value and *pI value
          480  +** and returns true.  If the input buffer does not match the patterns,
          481  +** no changes are made to either *pK or *pI and this routine returns false.
          482  +*/
          483  +static int isOffset(
          484  +  const unsigned char *zIn,  /* Text input */
          485  +  int nIn,                   /* Bytes of input */
          486  +  unsigned int *pK,          /* half-byte cursor to adjust */
          487  +  unsigned int *pI           /* Input index to adjust */
          488  +){
          489  +  int i;
          490  +  unsigned int k = 0;
          491  +  unsigned char c;
          492  +  for(i=1; i<nIn && (c = zIn[i])!=']'; i++){
          493  +    if( !isxdigit(c) ) return 0;
          494  +    k = k*16 + hexToInt(c);
          495  +  }
          496  +  if( i==nIn ) return 0;
          497  +  *pK = 2*k;
          498  +  *pI += i;
          499  +  return 1;
          500  +}
          501  +
          502  +/*
          503  +** Decode the text starting at zIn into a binary database file.
          504  +** The maximum length of zIn is nIn bytes.  Compute the binary database
          505  +** file contain in space obtained from sqlite3_malloc().
          506  +**
          507  +** Return the number of bytes of zIn consumed.  Or return -1 if there
          508  +** is an error.  One potential error is that the recipe specifies a
          509  +** database file larger than MX_FILE_SZ bytes.
          510  +**
          511  +** Abort on an OOM.
          512  +*/
          513  +static int decodeDatabase(
          514  +  const unsigned char *zIn,      /* Input text to be decoded */
          515  +  int nIn,                       /* Bytes of input text */
          516  +  unsigned char **paDecode,      /* OUT: decoded database file */
          517  +  int *pnDecode                  /* OUT: Size of decoded database */
          518  +){
          519  +  unsigned char *a;              /* Database under construction */
          520  +  int mx = 0;                    /* Current size of the database */
          521  +  sqlite3_uint64 nAlloc = 4096;  /* Space allocated in a[] */
          522  +  unsigned int i;                /* Next byte of zIn[] to read */
          523  +  unsigned int j;                /* Temporary integer */
          524  +  unsigned int k;                /* half-byte cursor index for output */
          525  +  unsigned int n;                /* Number of bytes of input */
          526  +  unsigned char b = 0;
          527  +  if( nIn<4 ) return -1;
          528  +  n = (unsigned int)nIn;
          529  +  a = sqlite3_malloc( nAlloc );
          530  +  if( a==0 ){
          531  +    fprintf(stderr, "Out of memory!\n");
          532  +    exit(1);
          533  +  }
          534  +  memset(a, 0, nAlloc);
          535  +  for(i=k=0; i<n; i++){
          536  +    char c = zIn[i];
          537  +    if( isxdigit(c) ){
          538  +      k++;
          539  +      if( k & 1 ){
          540  +        b = hexToInt(c)*16;
          541  +      }else{
          542  +        b += hexToInt(c);
          543  +        j = k/2 - 1;
          544  +        if( j>=nAlloc ){
          545  +          sqlite3_uint64 newSize;
          546  +          if( nAlloc==MX_FILE_SZ || j>=MX_FILE_SZ ){
          547  +            if( eVerbosity ){
          548  +              fprintf(stderr, "Input database too big: max %d bytes\n",
          549  +                      MX_FILE_SZ);
          550  +            }
          551  +            sqlite3_free(a);
          552  +            return -1;
          553  +          }
          554  +          newSize = nAlloc*2;
          555  +          if( newSize<=j ){
          556  +            newSize = (j+4096)&~4095;
          557  +          }
          558  +          if( newSize>MX_FILE_SZ ){
          559  +            if( j>=MX_FILE_SZ ){
          560  +              sqlite3_free(a);
          561  +              return -1;
          562  +            }
          563  +            newSize = MX_FILE_SZ;
          564  +          }
          565  +          a = sqlite3_realloc( a, newSize );
          566  +          if( a==0 ){
          567  +            fprintf(stderr, "Out of memory!\n");
          568  +            exit(1);
          569  +          }
          570  +          assert( newSize > nAlloc );
          571  +          memset(a+nAlloc, 0, newSize - nAlloc);
          572  +          nAlloc = newSize;
          573  +        }
          574  +        if( j>=(unsigned)mx ){
          575  +          mx = (j + 4095)&~4095;
          576  +          if( mx>MX_FILE_SZ ) mx = MX_FILE_SZ;
          577  +        }
          578  +        assert( j<nAlloc );
          579  +        a[j] = b;
          580  +      }
          581  +    }else if( zIn[i]=='[' && i<n-3 && isOffset(zIn+i, nIn-i, &k, &i) ){
          582  +      continue;
          583  +   }else if( zIn[i]=='\n' && i<n-4 && memcmp(zIn+i,"\n--\n",4)==0 ){
          584  +      i += 4;
          585  +      break;
          586  +    }
          587  +  }
          588  +  *pnDecode = mx;
          589  +  *paDecode = a;
          590  +  return i;
          591  +}
          592  +
          593  +/*
          594  +** Progress handler callback.
          595  +**
          596  +** The argument is the cutoff-time after which all processing should
          597  +** stop.  So return non-zero if the cut-off time is exceeded.
          598  +*/
          599  +static int progress_handler(void *pClientData) {
          600  +  FuzzCtx *p = (FuzzCtx*)pClientData;
          601  +  sqlite3_int64 iNow = timeOfDay();
          602  +  int rc = iNow>=p->iCutoffTime;
          603  +  sqlite3_int64 iDiff = iNow - p->iLastCb;
          604  +  if( iDiff > p->mxInterval ) p->mxInterval = iDiff;
          605  +  p->nCb++;
          606  +  if( rc==0 && p->mxCb>0 && p->mxCb<=p->nCb ) rc = 1;
          607  +  if( rc && !p->timeoutHit && eVerbosity>=2 ){
          608  +    printf("Timeout on progress callback %d\n", p->nCb);
          609  +    fflush(stdout);
          610  +    p->timeoutHit = 1;
          611  +  }
          612  +  return rc;
          613  +}
          614  +
          615  +/*
          616  +** Disallow debugging pragmas such as "PRAGMA vdbe_debug" and
          617  +** "PRAGMA parser_trace" since they can dramatically increase the
          618  +** amount of output without actually testing anything useful.
          619  +**
          620  +** Also block ATTACH and DETACH
          621  +*/
          622  +static int block_troublesome_sql(
          623  +  void *Notused,
          624  +  int eCode,
          625  +  const char *zArg1,
          626  +  const char *zArg2,
          627  +  const char *zArg3,
          628  +  const char *zArg4
          629  +){
          630  +  (void)Notused;
          631  +  (void)zArg2;
          632  +  (void)zArg3;
          633  +  (void)zArg4;
          634  +  if( eCode==SQLITE_PRAGMA ){
          635  +    if( sqlite3_strnicmp("vdbe_", zArg1, 5)==0
          636  +     || sqlite3_stricmp("parser_trace", zArg1)==0
          637  +     || sqlite3_stricmp("temp_store_directory", zArg1)==0
          638  +    ){
          639  +      return SQLITE_DENY;
          640  +    }
          641  +  }else if( (eCode==SQLITE_ATTACH || eCode==SQLITE_DETACH)
          642  +            && zArg1 && zArg1[0] ){
          643  +    return SQLITE_DENY;
          644  +  }
          645  +  return SQLITE_OK;
          646  +}
          647  +
          648  +/*
          649  +** Run the SQL text
          650  +*/
          651  +static int runDbSql(sqlite3 *db, const char *zSql){
          652  +  int rc;
          653  +  sqlite3_stmt *pStmt;
          654  +  while( isspace(zSql[0]) ) zSql++;
          655  +  if( zSql[0]==0 ) return SQLITE_OK;
          656  +  if( eVerbosity>=4 ){
          657  +    printf("RUNNING-SQL: [%s]\n", zSql);
          658  +    fflush(stdout);
          659  +  }
          660  +  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
          661  +  if( rc==SQLITE_OK ){
          662  +    while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
          663  +      if( eVerbosity>=5 ){
          664  +        int j;
          665  +        for(j=0; j<sqlite3_column_count(pStmt); j++){
          666  +          if( j ) printf(",");
          667  +          switch( sqlite3_column_type(pStmt, j) ){
          668  +            case SQLITE_NULL: {
          669  +              printf("NULL");
          670  +              break;
          671  +            }
          672  +            case SQLITE_INTEGER:
          673  +            case SQLITE_FLOAT: {
          674  +              printf("%s", sqlite3_column_text(pStmt, j));
          675  +              break;
          676  +            }
          677  +            case SQLITE_BLOB: {
          678  +              int n = sqlite3_column_bytes(pStmt, j);
          679  +              int i;
          680  +              const unsigned char *a;
          681  +              a = (const unsigned char*)sqlite3_column_blob(pStmt, j);
          682  +              printf("x'");
          683  +              for(i=0; i<n; i++){
          684  +                printf("%02x", a[i]);
          685  +              }
          686  +              printf("'");
          687  +              break;
          688  +            }
          689  +            case SQLITE_TEXT: {
          690  +              int n = sqlite3_column_bytes(pStmt, j);
          691  +              int i;
          692  +              const unsigned char *a;
          693  +              a = (const unsigned char*)sqlite3_column_blob(pStmt, j);
          694  +              printf("'");
          695  +              for(i=0; i<n; i++){
          696  +                if( a[i]=='\'' ){
          697  +                  printf("''");
          698  +                }else{
          699  +                  putchar(a[i]);
          700  +                }
          701  +              }
          702  +              printf("'");
          703  +              break;
          704  +            }
          705  +          } /* End switch() */
          706  +        } /* End for() */
          707  +        printf("\n");
          708  +        fflush(stdout);
          709  +      } /* End if( eVerbosity>=5 ) */
          710  +    } /* End while( SQLITE_ROW */
          711  +    if( rc!=SQLITE_DONE && eVerbosity>=4 ){
          712  +      printf("SQL-ERROR: (%d) %s\n", rc, sqlite3_errmsg(db));
          713  +      fflush(stdout);
          714  +    }
          715  +  }else if( eVerbosity>=4 ){
          716  +    printf("SQL-ERROR (%d): %s\n", rc, sqlite3_errmsg(db));
          717  +    fflush(stdout);    
          718  +  } /* End if( SQLITE_OK ) */
          719  +  return sqlite3_finalize(pStmt);
          720  +}
          721  +
          722  +/* Invoke this routine to run a single test case */
          723  +int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte){
          724  +  int rc;                    /* SQLite API return value */
          725  +  int iSql;                  /* Index in aData[] of start of SQL */
          726  +  unsigned char *aDb = 0;    /* Decoded database content */
          727  +  int nDb = 0;               /* Size of the decoded database */
          728  +  int i;                     /* Loop counter */
          729  +  int j;                     /* Start of current SQL statement */
          730  +  char *zSql = 0;            /* SQL text to run */
          731  +  int nSql;                  /* Bytes of SQL text */
          732  +  FuzzCtx cx;                /* Fuzzing context */
          733  +
          734  +  if( nByte<10 ) return 0;
          735  +  if( sqlite3_initialize() ) return 0;
          736  +  if( sqlite3_memory_used()!=0 ){
          737  +    int nAlloc = 0;
          738  +    int nNotUsed = 0;
          739  +    sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &nAlloc, &nNotUsed, 0);
          740  +    fprintf(stderr,"Memory leak in mutator: %lld bytes in %d allocations\n",
          741  +            sqlite3_memory_used(), nAlloc);
          742  +    exit(1);
          743  +  }
          744  +  memset(&cx, 0, sizeof(cx));
          745  +  iSql = decodeDatabase((unsigned char*)aData, (int)nByte, &aDb, &nDb);
          746  +  if( iSql<0 ) return 0;
          747  +  nSql = nByte - iSql;
          748  +  if( eVerbosity>=3 ){
          749  +    printf(
          750  +      "****** %d-byte input, %d-byte database, %d-byte script "
          751  +      "******\n", (int)nByte, nDb, nSql);
          752  +    fflush(stdout);
          753  +  }
          754  +  rc = sqlite3_open(0, &cx.db);
          755  +  if( rc ) return 1;
          756  +  if( bVdbeDebug ){
          757  +    sqlite3_exec(cx.db, "PRAGMA vdbe_debug=ON", 0, 0, 0);
          758  +  }
          759  +
          760  +  /* Invoke the progress handler frequently to check to see if we
          761  +  ** are taking too long.  The progress handler will return true
          762  +  ** (which will block further processing) if more than iTimeout seconds have
          763  +  ** elapsed since the start of the test.
          764  +  */
          765  +  cx.iLastCb = timeOfDay();
          766  +  cx.iCutoffTime = cx.iLastCb + iTimeout;  /* Now + iTimeout seconds */
          767  +  cx.mxCb = mxProgressCb;
          768  +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
          769  +  sqlite3_progress_handler(cx.db, 10, progress_handler, (void*)&cx);
          770  +#endif
          771  +
          772  +  /* Set a limit on the maximum size of a prepared statement, and the
          773  +  ** maximum length of a string or blob */
          774  +  if( vdbeOpLimit>0 ){
          775  +    sqlite3_limit(cx.db, SQLITE_LIMIT_VDBE_OP, vdbeOpLimit);
          776  +  }
          777  +  if( lengthLimit>0 ){
          778  +    sqlite3_limit(cx.db, SQLITE_LIMIT_LENGTH, lengthLimit);
          779  +  }
          780  +
          781  +  if( nDb>=20 && aDb[18]==2 && aDb[19]==2 ){
          782  +    aDb[18] = aDb[19] = 1;
          783  +  }
          784  +  rc = sqlite3_deserialize(cx.db, "main", aDb, nDb, nDb,
          785  +          SQLITE_DESERIALIZE_RESIZEABLE |
          786  +          SQLITE_DESERIALIZE_FREEONCLOSE);
          787  +  if( rc ){
          788  +    fprintf(stderr, "sqlite3_deserialize() failed with %d\n", rc);
          789  +    goto testrun_finished;
          790  +  }
          791  +  if( maxDbSize>0 ){
          792  +    sqlite3_int64 x = maxDbSize;
          793  +    sqlite3_file_control(cx.db, "main", SQLITE_FCNTL_SIZE_LIMIT, &x);
          794  +  }
          795  +
          796  +  /* For high debugging levels, turn on debug mode */
          797  +  if( eVerbosity>=5 ){
          798  +    sqlite3_exec(cx.db, "PRAGMA vdbe_debug=ON;", 0, 0, 0);
          799  +  }
          800  +
          801  +  /* Block debug pragmas and ATTACH/DETACH.  But wait until after
          802  +  ** deserialize to do this because deserialize depends on ATTACH */
          803  +  sqlite3_set_authorizer(cx.db, block_troublesome_sql, 0);
          804  +
          805  +  /* Consistent PRNG seed */
          806  +  sqlite3_randomness(0,0);
          807  +
          808  +  zSql = sqlite3_malloc( nSql + 1 );
          809  +  if( zSql==0 ){
          810  +    fprintf(stderr, "Out of memory!\n");
          811  +  }else{
          812  +    memcpy(zSql, aData+iSql, nSql);
          813  +    zSql[nSql] = 0;
          814  +    for(i=j=0; zSql[i]; i++){
          815  +      if( zSql[i]==';' ){
          816  +        char cSaved = zSql[i+1];
          817  +        zSql[i+1] = 0;
          818  +        if( sqlite3_complete(zSql+j) ){
          819  +          rc = runDbSql(cx.db, zSql+j);
          820  +          j = i+1;
          821  +        }
          822  +        zSql[i+1] = cSaved;
          823  +        if( rc==SQLITE_INTERRUPT || progress_handler(&cx) ){
          824  +          goto testrun_finished;
          825  +        }
          826  +      }
          827  +    }
          828  +    if( j<i ){
          829  +      runDbSql(cx.db, zSql+j);
          830  +    }
          831  +  }
          832  +testrun_finished:
          833  +  sqlite3_free(zSql);
          834  +  rc = sqlite3_close(cx.db);
          835  +  if( rc!=SQLITE_OK ){
          836  +    fprintf(stdout, "sqlite3_close() returns %d\n", rc);
          837  +  }
          838  +  if( eVerbosity>=2 ){
          839  +    fprintf(stdout, "Peak memory usages: %f MB\n",
          840  +       sqlite3_memory_highwater(1) / 1000000.0);
          841  +  }
          842  +  if( sqlite3_memory_used()!=0 ){
          843  +    int nAlloc = 0;
          844  +    int nNotUsed = 0;
          845  +    sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &nAlloc, &nNotUsed, 0);
          846  +    fprintf(stderr,"Memory leak: %lld bytes in %d allocations\n",
          847  +            sqlite3_memory_used(), nAlloc);
          848  +    exit(1);
          849  +  }
          850  +  return 0;
          851  +}
          852  +
          853  +/*
          854  +** END of the dbsqlfuzz code
          855  +***************************************************************************/
          856  +
          857  +/* Look at a SQL text and try to determine if it begins with a database
          858  +** description, such as would be found in a dbsqlfuzz test case.  Return
          859  +** true if this does appear to be a dbsqlfuzz test case and false otherwise.
          860  +*/
          861  +static int isDbSql(unsigned char *a, int n){
          862  +  unsigned char buf[12];
          863  +  int i;
          864  +  if( n>4 && memcmp(a,"\n--\n",4)==0 ) return 1;
          865  +  while( n>0 && isspace(a[0]) ){ a++; n--; }
          866  +  for(i=0; n>0 && i<8; n--, a++){
          867  +    if( isxdigit(a[0]) ) buf[i++] = a[0];
          868  +  }
          869  +  if( i==8 && memcmp(buf,"53514c69",8)==0 ) return 1;
          870  +  return 0;
          871  +}
          872  +
   421    873   
   422    874   /* Methods for the VHandle object
   423    875   */
   424    876   static int inmemClose(sqlite3_file *pFile){
   425    877     VHandle *p = (VHandle*)pFile;
   426    878     VFile *pVFile = p->pVFile;
   427    879     pVFile->nRef--;
................................................................................
   790   1242         v *= aMult[i].iMult;
   791   1243         break;
   792   1244       }
   793   1245     }
   794   1246     if( v>0x7fffffff ) fatalError("parameter too large - max 2147483648");
   795   1247     return (int)(isNeg? -v : v);
   796   1248   }
         1249  +
         1250  +/*
         1251  +** Return the number of "v" characters in a string.  Return 0 if there
         1252  +** are any characters in the string other than "v".
         1253  +*/
         1254  +static int numberOfVChar(const char *z){
         1255  +  int N = 0;
         1256  +  while( z[0] && z[0]=='v' ){
         1257  +    z++;
         1258  +    N++;
         1259  +  }
         1260  +  return z[0]==0 ? N : 0;
         1261  +}
   797   1262   
   798   1263   /*
   799   1264   ** Print sketchy documentation for this utility program
   800   1265   */
   801   1266   static void showHelp(void){
   802   1267     printf("Usage: %s [options] SOURCE-DB ?ARGS...?\n", g.zArgv0);
   803   1268     printf(
................................................................................
   864   1329     char *zExpSql = 0;           /* Write SQL to files in this directory */
   865   1330     void *pHeap = 0;             /* Heap for use by SQLite */
   866   1331     int ossFuzz = 0;             /* enable OSS-FUZZ testing */
   867   1332     int ossFuzzThisDb = 0;       /* ossFuzz value for this particular database */
   868   1333     int nativeMalloc = 0;        /* Turn off MEMSYS3/5 and lookaside if true */
   869   1334     sqlite3_vfs *pDfltVfs;       /* The default VFS */
   870   1335     int openFlags4Data;          /* Flags for sqlite3_open_v2() */
         1336  +  int nV;                      /* How much to increase verbosity with -vvvv */
   871   1337   
   872   1338     sqlite3_initialize();
   873   1339     iBegin = timeOfDay();
   874   1340   #ifdef __unix__
   875   1341     signal(SIGALRM, timeoutHandler);
   876   1342   #endif
   877   1343     g.zArgv0 = argv[0];
................................................................................
   947   1413         if( strcmp(z,"prng-seed")==0 ){
   948   1414           if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
   949   1415           g.uRandom = atoi(argv[++i]);
   950   1416         }else
   951   1417         if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
   952   1418           quietFlag = 1;
   953   1419           verboseFlag = 0;
         1420  +        eVerbosity = 0;
   954   1421         }else
   955   1422         if( strcmp(z,"rebuild")==0 ){
   956   1423           rebuildFlag = 1;
   957   1424           openFlags4Data = SQLITE_OPEN_READWRITE;
   958   1425         }else
   959   1426         if( strcmp(z,"result-trace")==0 ){
   960   1427           runFlags |= SQL_OUTPUT;
................................................................................
   969   1436         }else
   970   1437         if( strcmp(z,"timeout-test")==0 ){
   971   1438           timeoutTest = 1;
   972   1439   #ifndef __unix__
   973   1440           fatalError("timeout is not available on non-unix systems");
   974   1441   #endif
   975   1442         }else
   976         -      if( strcmp(z,"verbose")==0 || strcmp(z,"v")==0 ){
         1443  +      if( strcmp(z,"verbose")==0 ){
   977   1444           quietFlag = 0;
   978   1445           verboseFlag++;
         1446  +        eVerbosity++;
         1447  +        if( verboseFlag>1 ) runFlags |= SQL_TRACE;
         1448  +      }else
         1449  +      if( (nV = numberOfVChar(z))>=1 ){
         1450  +        quietFlag = 0;
         1451  +        verboseFlag += nV;
         1452  +        eVerbosity += nV;
   979   1453           if( verboseFlag>1 ) runFlags |= SQL_TRACE;
         1454  +      }else
         1455  +      if( strcmp(z,"version")==0 ){
         1456  +        int ii;
         1457  +        const char *z;
         1458  +        printf("SQLite %s %s\n", sqlite3_libversion(), sqlite3_sourceid());
         1459  +        for(ii=0; (z = sqlite3_compileoption_get(ii))!=0; ii++){
         1460  +          printf("%s\n", z);
         1461  +        }
         1462  +        return 0;
   980   1463         }else
   981   1464         {
   982   1465           fatalError("unknown option: %s", argv[i]);
   983   1466         }
   984   1467       }else{
   985   1468         nSrcDb++;
   986   1469         azSrcDb = safe_realloc(azSrcDb, nSrcDb*sizeof(azSrcDb[0]));
................................................................................
  1226   1709       /* Reset the in-memory virtual filesystem */
  1227   1710       formatVfs();
  1228   1711       
  1229   1712       /* Run a test using each SQL script against each database.
  1230   1713       */
  1231   1714       if( !verboseFlag && !quietFlag ) printf("%s:", zDbName);
  1232   1715       for(pSql=g.pFirstSql; pSql; pSql=pSql->pNext){
         1716  +      if( isDbSql(pSql->a, pSql->sz) ){
         1717  +        sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d",pSql->id);
         1718  +        if( verboseFlag ){
         1719  +          printf("%s\n", g.zTestName);
         1720  +          fflush(stdout);
         1721  +        }else if( !quietFlag ){
         1722  +          static int prevAmt = -1;
         1723  +          int idx = pSql->seq;
         1724  +          int amt = idx*10/(g.nSql);
         1725  +          if( amt!=prevAmt ){
         1726  +            printf(" %d%%", amt*10);
         1727  +            fflush(stdout);
         1728  +            prevAmt = amt;
         1729  +          }
         1730  +        }
         1731  +        runCombinedDbSqlInput(pSql->a, pSql->sz);
         1732  +        nTest++;
         1733  +        g.zTestName[0] = 0;
         1734  +        continue;
         1735  +      }
  1233   1736         for(pDb=g.pFirstDb; pDb; pDb=pDb->pNext){
  1234   1737           int openFlags;
  1235   1738           const char *zVfs = "inmem";
  1236   1739           sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d,dbid=%d",
  1237   1740                            pSql->id, pDb->id);
  1238   1741           if( verboseFlag ){
  1239   1742             printf("%s\n", g.zTestName);

Added test/fuzzdata8.db.

cannot compute difference between binary files