modernc.org/cc@v1.0.1/v2/testdata/_sqlite/test/fuzzcheck.c (about)

     1  /*
     2  ** 2015-05-25
     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 regressions tests on
    14  ** the SQLite library using data from an external fuzzer, such as American
    15  ** Fuzzy Lop (AFL) (http://lcamtuf.coredump.cx/afl/).
    16  **
    17  ** This program reads content from an SQLite database file with the following
    18  ** schema:
    19  **
    20  **     CREATE TABLE db(
    21  **       dbid INTEGER PRIMARY KEY, -- database id
    22  **       dbcontent BLOB            -- database disk file image
    23  **     );
    24  **     CREATE TABLE xsql(
    25  **       sqlid INTEGER PRIMARY KEY,   -- SQL script id
    26  **       sqltext TEXT                 -- Text of SQL statements to run
    27  **     );
    28  **     CREATE TABLE IF NOT EXISTS readme(
    29  **       msg TEXT -- Human-readable description of this test collection
    30  **     );
    31  **
    32  ** For each database file in the DB table, the SQL text in the XSQL table
    33  ** is run against that database.  All README.MSG values are printed prior
    34  ** to the start of the test (unless the --quiet option is used).  If the
    35  ** DB table is empty, then all entries in XSQL are run against an empty
    36  ** in-memory database.
    37  **
    38  ** This program is looking for crashes, assertion faults, and/or memory leaks.
    39  ** No attempt is made to verify the output.  The assumption is that either all
    40  ** of the database files or all of the SQL statements are malformed inputs,
    41  ** generated by a fuzzer, that need to be checked to make sure they do not
    42  ** present a security risk.
    43  **
    44  ** This program also includes some command-line options to help with 
    45  ** creation and maintenance of the source content database.  The command
    46  **
    47  **     ./fuzzcheck database.db --load-sql FILE...
    48  **
    49  ** Loads all FILE... arguments into the XSQL table.  The --load-db option
    50  ** works the same but loads the files into the DB table.  The -m option can
    51  ** be used to initialize the README table.  The "database.db" file is created
    52  ** if it does not previously exist.  Example:
    53  **
    54  **     ./fuzzcheck new.db --load-sql *.sql
    55  **     ./fuzzcheck new.db --load-db *.db
    56  **     ./fuzzcheck new.db -m 'New test cases'
    57  **
    58  ** The three commands above will create the "new.db" file and initialize all
    59  ** tables.  Then do "./fuzzcheck new.db" to run the tests.
    60  **
    61  ** DEBUGGING HINTS:
    62  **
    63  ** If fuzzcheck does crash, it can be run in the debugger and the content
    64  ** of the global variable g.zTextName[] will identify the specific XSQL and
    65  ** DB values that were running when the crash occurred.
    66  */
    67  #include <stdio.h>
    68  #include <stdlib.h>
    69  #include <string.h>
    70  #include <stdarg.h>
    71  #include <ctype.h>
    72  #include "sqlite3.h"
    73  #define ISSPACE(X) isspace((unsigned char)(X))
    74  #define ISDIGIT(X) isdigit((unsigned char)(X))
    75  
    76  
    77  #ifdef __unix__
    78  # include <signal.h>
    79  # include <unistd.h>
    80  #endif
    81  
    82  #ifdef SQLITE_OSS_FUZZ
    83  # include <stddef.h>
    84  # include <stdint.h>
    85  #endif
    86  
    87  /*
    88  ** Files in the virtual file system.
    89  */
    90  typedef struct VFile VFile;
    91  struct VFile {
    92    char *zFilename;        /* Filename.  NULL for delete-on-close. From malloc() */
    93    int sz;                 /* Size of the file in bytes */
    94    int nRef;               /* Number of references to this file */
    95    unsigned char *a;       /* Content of the file.  From malloc() */
    96  };
    97  typedef struct VHandle VHandle;
    98  struct VHandle {
    99    sqlite3_file base;      /* Base class.  Must be first */
   100    VFile *pVFile;          /* The underlying file */
   101  };
   102  
   103  /*
   104  ** The value of a database file template, or of an SQL script
   105  */
   106  typedef struct Blob Blob;
   107  struct Blob {
   108    Blob *pNext;            /* Next in a list */
   109    int id;                 /* Id of this Blob */
   110    int seq;                /* Sequence number */
   111    int sz;                 /* Size of this Blob in bytes */
   112    unsigned char a[1];     /* Blob content.  Extra space allocated as needed. */
   113  };
   114  
   115  /*
   116  ** Maximum number of files in the in-memory virtual filesystem.
   117  */
   118  #define MX_FILE  10
   119  
   120  /*
   121  ** Maximum allowed file size
   122  */
   123  #define MX_FILE_SZ 10000000
   124  
   125  /*
   126  ** All global variables are gathered into the "g" singleton.
   127  */
   128  static struct GlobalVars {
   129    const char *zArgv0;              /* Name of program */
   130    VFile aFile[MX_FILE];            /* The virtual filesystem */
   131    int nDb;                         /* Number of template databases */
   132    Blob *pFirstDb;                  /* Content of first template database */
   133    int nSql;                        /* Number of SQL scripts */
   134    Blob *pFirstSql;                 /* First SQL script */
   135    unsigned int uRandom;            /* Seed for the SQLite PRNG */
   136    char zTestName[100];             /* Name of current test */
   137  } g;
   138  
   139  /*
   140  ** Print an error message and quit.
   141  */
   142  static void fatalError(const char *zFormat, ...){
   143    va_list ap;
   144    if( g.zTestName[0] ){
   145      fprintf(stderr, "%s (%s): ", g.zArgv0, g.zTestName);
   146    }else{
   147      fprintf(stderr, "%s: ", g.zArgv0);
   148    }
   149    va_start(ap, zFormat);
   150    vfprintf(stderr, zFormat, ap);
   151    va_end(ap);
   152    fprintf(stderr, "\n");
   153    exit(1);
   154  }
   155  
   156  /*
   157  ** Timeout handler
   158  */
   159  #ifdef __unix__
   160  static void timeoutHandler(int NotUsed){
   161    (void)NotUsed;
   162    fatalError("timeout\n");
   163  }
   164  #endif
   165  
   166  /*
   167  ** Set the an alarm to go off after N seconds.  Disable the alarm
   168  ** if N==0
   169  */
   170  static void setAlarm(int N){
   171  #ifdef __unix__
   172    alarm(N);
   173  #else
   174    (void)N;
   175  #endif
   176  }
   177  
   178  #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
   179  /*
   180  ** This an SQL progress handler.  After an SQL statement has run for
   181  ** many steps, we want to interrupt it.  This guards against infinite
   182  ** loops from recursive common table expressions.
   183  **
   184  ** *pVdbeLimitFlag is true if the --limit-vdbe command-line option is used.
   185  ** In that case, hitting the progress handler is a fatal error.
   186  */
   187  static int progressHandler(void *pVdbeLimitFlag){
   188    if( *(int*)pVdbeLimitFlag ) fatalError("too many VDBE cycles");
   189    return 1;
   190  }
   191  #endif
   192  
   193  /*
   194  ** Reallocate memory.  Show and error and quit if unable.
   195  */
   196  static void *safe_realloc(void *pOld, int szNew){
   197    void *pNew = realloc(pOld, szNew<=0 ? 1 : szNew);
   198    if( pNew==0 ) fatalError("unable to realloc for %d bytes", szNew);
   199    return pNew;
   200  }
   201  
   202  /*
   203  ** Initialize the virtual file system.
   204  */
   205  static void formatVfs(void){
   206    int i;
   207    for(i=0; i<MX_FILE; i++){
   208      g.aFile[i].sz = -1;
   209      g.aFile[i].zFilename = 0;
   210      g.aFile[i].a = 0;
   211      g.aFile[i].nRef = 0;
   212    }
   213  }
   214  
   215  
   216  /*
   217  ** Erase all information in the virtual file system.
   218  */
   219  static void reformatVfs(void){
   220    int i;
   221    for(i=0; i<MX_FILE; i++){
   222      if( g.aFile[i].sz<0 ) continue;
   223      if( g.aFile[i].zFilename ){
   224        free(g.aFile[i].zFilename);
   225        g.aFile[i].zFilename = 0;
   226      }
   227      if( g.aFile[i].nRef>0 ){
   228        fatalError("file %d still open.  nRef=%d", i, g.aFile[i].nRef);
   229      }
   230      g.aFile[i].sz = -1;
   231      free(g.aFile[i].a);
   232      g.aFile[i].a = 0;
   233      g.aFile[i].nRef = 0;
   234    }
   235  }
   236  
   237  /*
   238  ** Find a VFile by name
   239  */
   240  static VFile *findVFile(const char *zName){
   241    int i;
   242    if( zName==0 ) return 0;
   243    for(i=0; i<MX_FILE; i++){
   244      if( g.aFile[i].zFilename==0 ) continue;   
   245      if( strcmp(g.aFile[i].zFilename, zName)==0 ) return &g.aFile[i];
   246    }
   247    return 0;
   248  }
   249  
   250  /*
   251  ** Find a VFile by name.  Create it if it does not already exist and
   252  ** initialize it to the size and content given.
   253  **
   254  ** Return NULL only if the filesystem is full.
   255  */
   256  static VFile *createVFile(const char *zName, int sz, unsigned char *pData){
   257    VFile *pNew = findVFile(zName);
   258    int i;
   259    if( pNew ) return pNew;
   260    for(i=0; i<MX_FILE && g.aFile[i].sz>=0; i++){}
   261    if( i>=MX_FILE ) return 0;
   262    pNew = &g.aFile[i];
   263    if( zName ){
   264      int nName = (int)strlen(zName)+1;
   265      pNew->zFilename = safe_realloc(0, nName);
   266      memcpy(pNew->zFilename, zName, nName);
   267    }else{
   268      pNew->zFilename = 0;
   269    }
   270    pNew->nRef = 0;
   271    pNew->sz = sz;
   272    pNew->a = safe_realloc(0, sz);
   273    if( sz>0 ) memcpy(pNew->a, pData, sz);
   274    return pNew;
   275  }
   276  
   277  
   278  /*
   279  ** Implementation of the "readfile(X)" SQL function.  The entire content
   280  ** of the file named X is read and returned as a BLOB.  NULL is returned
   281  ** if the file does not exist or is unreadable.
   282  */
   283  static void readfileFunc(
   284    sqlite3_context *context,
   285    int argc,
   286    sqlite3_value **argv
   287  ){
   288    const char *zName;
   289    FILE *in;
   290    long nIn;
   291    void *pBuf;
   292  
   293    zName = (const char*)sqlite3_value_text(argv[0]);
   294    if( zName==0 ) return;
   295    in = fopen(zName, "rb");
   296    if( in==0 ) return;
   297    fseek(in, 0, SEEK_END);
   298    nIn = ftell(in);
   299    rewind(in);
   300    pBuf = sqlite3_malloc64( nIn );
   301    if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
   302      sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
   303    }else{
   304      sqlite3_free(pBuf);
   305    }
   306    fclose(in);
   307  }
   308  
   309  /*
   310  ** Implementation of the "writefile(X,Y)" SQL function.  The argument Y
   311  ** is written into file X.  The number of bytes written is returned.  Or
   312  ** NULL is returned if something goes wrong, such as being unable to open
   313  ** file X for writing.
   314  */
   315  static void writefileFunc(
   316    sqlite3_context *context,
   317    int argc,
   318    sqlite3_value **argv
   319  ){
   320    FILE *out;
   321    const char *z;
   322    sqlite3_int64 rc;
   323    const char *zFile;
   324  
   325    (void)argc;
   326    zFile = (const char*)sqlite3_value_text(argv[0]);
   327    if( zFile==0 ) return;
   328    out = fopen(zFile, "wb");
   329    if( out==0 ) return;
   330    z = (const char*)sqlite3_value_blob(argv[1]);
   331    if( z==0 ){
   332      rc = 0;
   333    }else{
   334      rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
   335    }
   336    fclose(out);
   337    sqlite3_result_int64(context, rc);
   338  }
   339  
   340  
   341  /*
   342  ** Load a list of Blob objects from the database
   343  */
   344  static void blobListLoadFromDb(
   345    sqlite3 *db,             /* Read from this database */
   346    const char *zSql,        /* Query used to extract the blobs */
   347    int onlyId,              /* Only load where id is this value */
   348    int *pN,                 /* OUT: Write number of blobs loaded here */
   349    Blob **ppList            /* OUT: Write the head of the blob list here */
   350  ){
   351    Blob head;
   352    Blob *p;
   353    sqlite3_stmt *pStmt;
   354    int n = 0;
   355    int rc;
   356    char *z2;
   357  
   358    if( onlyId>0 ){
   359      z2 = sqlite3_mprintf("%s WHERE rowid=%d", zSql, onlyId);
   360    }else{
   361      z2 = sqlite3_mprintf("%s", zSql);
   362    }
   363    rc = sqlite3_prepare_v2(db, z2, -1, &pStmt, 0);
   364    sqlite3_free(z2);
   365    if( rc ) fatalError("%s", sqlite3_errmsg(db));
   366    head.pNext = 0;
   367    p = &head;
   368    while( SQLITE_ROW==sqlite3_step(pStmt) ){
   369      int sz = sqlite3_column_bytes(pStmt, 1);
   370      Blob *pNew = safe_realloc(0, sizeof(*pNew)+sz );
   371      pNew->id = sqlite3_column_int(pStmt, 0);
   372      pNew->sz = sz;
   373      pNew->seq = n++;
   374      pNew->pNext = 0;
   375      memcpy(pNew->a, sqlite3_column_blob(pStmt,1), sz);
   376      pNew->a[sz] = 0;
   377      p->pNext = pNew;
   378      p = pNew;
   379    }
   380    sqlite3_finalize(pStmt);
   381    *pN = n;
   382    *ppList = head.pNext;
   383  }
   384  
   385  /*
   386  ** Free a list of Blob objects
   387  */
   388  static void blobListFree(Blob *p){
   389    Blob *pNext;
   390    while( p ){
   391      pNext = p->pNext;
   392      free(p);
   393      p = pNext;
   394    }
   395  }
   396  
   397  
   398  /* Return the current wall-clock time */
   399  static sqlite3_int64 timeOfDay(void){
   400    static sqlite3_vfs *clockVfs = 0;
   401    sqlite3_int64 t;
   402    if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
   403    if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
   404      clockVfs->xCurrentTimeInt64(clockVfs, &t);
   405    }else{
   406      double r;
   407      clockVfs->xCurrentTime(clockVfs, &r);
   408      t = (sqlite3_int64)(r*86400000.0);
   409    }
   410    return t;
   411  }
   412  
   413  /* Methods for the VHandle object
   414  */
   415  static int inmemClose(sqlite3_file *pFile){
   416    VHandle *p = (VHandle*)pFile;
   417    VFile *pVFile = p->pVFile;
   418    pVFile->nRef--;
   419    if( pVFile->nRef==0 && pVFile->zFilename==0 ){
   420      pVFile->sz = -1;
   421      free(pVFile->a);
   422      pVFile->a = 0;
   423    }
   424    return SQLITE_OK;
   425  }
   426  static int inmemRead(
   427    sqlite3_file *pFile,   /* Read from this open file */
   428    void *pData,           /* Store content in this buffer */
   429    int iAmt,              /* Bytes of content */
   430    sqlite3_int64 iOfst    /* Start reading here */
   431  ){
   432    VHandle *pHandle = (VHandle*)pFile;
   433    VFile *pVFile = pHandle->pVFile;
   434    if( iOfst<0 || iOfst>=pVFile->sz ){
   435      memset(pData, 0, iAmt);
   436      return SQLITE_IOERR_SHORT_READ;
   437    }
   438    if( iOfst+iAmt>pVFile->sz ){
   439      memset(pData, 0, iAmt);
   440      iAmt = (int)(pVFile->sz - iOfst);
   441      memcpy(pData, pVFile->a, iAmt);
   442      return SQLITE_IOERR_SHORT_READ;
   443    }
   444    memcpy(pData, pVFile->a + iOfst, iAmt);
   445    return SQLITE_OK;
   446  }
   447  static int inmemWrite(
   448    sqlite3_file *pFile,   /* Write to this file */
   449    const void *pData,     /* Content to write */
   450    int iAmt,              /* bytes to write */
   451    sqlite3_int64 iOfst    /* Start writing here */
   452  ){
   453    VHandle *pHandle = (VHandle*)pFile;
   454    VFile *pVFile = pHandle->pVFile;
   455    if( iOfst+iAmt > pVFile->sz ){
   456      if( iOfst+iAmt >= MX_FILE_SZ ){
   457        return SQLITE_FULL;
   458      }
   459      pVFile->a = safe_realloc(pVFile->a, (int)(iOfst+iAmt));
   460      if( iOfst > pVFile->sz ){
   461        memset(pVFile->a + pVFile->sz, 0, (int)(iOfst - pVFile->sz));
   462      }
   463      pVFile->sz = (int)(iOfst + iAmt);
   464    }
   465    memcpy(pVFile->a + iOfst, pData, iAmt);
   466    return SQLITE_OK;
   467  }
   468  static int inmemTruncate(sqlite3_file *pFile, sqlite3_int64 iSize){
   469    VHandle *pHandle = (VHandle*)pFile;
   470    VFile *pVFile = pHandle->pVFile;
   471    if( pVFile->sz>iSize && iSize>=0 ) pVFile->sz = (int)iSize;
   472    return SQLITE_OK;
   473  }
   474  static int inmemSync(sqlite3_file *pFile, int flags){
   475    return SQLITE_OK;
   476  }
   477  static int inmemFileSize(sqlite3_file *pFile, sqlite3_int64 *pSize){
   478    *pSize = ((VHandle*)pFile)->pVFile->sz;
   479    return SQLITE_OK;
   480  }
   481  static int inmemLock(sqlite3_file *pFile, int type){
   482    return SQLITE_OK;
   483  }
   484  static int inmemUnlock(sqlite3_file *pFile, int type){
   485    return SQLITE_OK;
   486  }
   487  static int inmemCheckReservedLock(sqlite3_file *pFile, int *pOut){
   488    *pOut = 0;
   489    return SQLITE_OK;
   490  }
   491  static int inmemFileControl(sqlite3_file *pFile, int op, void *pArg){
   492    return SQLITE_NOTFOUND;
   493  }
   494  static int inmemSectorSize(sqlite3_file *pFile){
   495    return 512;
   496  }
   497  static int inmemDeviceCharacteristics(sqlite3_file *pFile){
   498    return
   499        SQLITE_IOCAP_SAFE_APPEND |
   500        SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
   501        SQLITE_IOCAP_POWERSAFE_OVERWRITE;
   502  }
   503  
   504  
   505  /* Method table for VHandle
   506  */
   507  static sqlite3_io_methods VHandleMethods = {
   508    /* iVersion  */    1,
   509    /* xClose    */    inmemClose,
   510    /* xRead     */    inmemRead,
   511    /* xWrite    */    inmemWrite,
   512    /* xTruncate */    inmemTruncate,
   513    /* xSync     */    inmemSync,
   514    /* xFileSize */    inmemFileSize,
   515    /* xLock     */    inmemLock,
   516    /* xUnlock   */    inmemUnlock,
   517    /* xCheck... */    inmemCheckReservedLock,
   518    /* xFileCtrl */    inmemFileControl,
   519    /* xSectorSz */    inmemSectorSize,
   520    /* xDevchar  */    inmemDeviceCharacteristics,
   521    /* xShmMap   */    0,
   522    /* xShmLock  */    0,
   523    /* xShmBarrier */  0,
   524    /* xShmUnmap */    0,
   525    /* xFetch    */    0,
   526    /* xUnfetch  */    0
   527  };
   528  
   529  /*
   530  ** Open a new file in the inmem VFS.  All files are anonymous and are
   531  ** delete-on-close.
   532  */
   533  static int inmemOpen(
   534    sqlite3_vfs *pVfs,
   535    const char *zFilename,
   536    sqlite3_file *pFile,
   537    int openFlags,
   538    int *pOutFlags
   539  ){
   540    VFile *pVFile = createVFile(zFilename, 0, (unsigned char*)"");
   541    VHandle *pHandle = (VHandle*)pFile;
   542    if( pVFile==0 ){
   543      return SQLITE_FULL;
   544    }
   545    pHandle->pVFile = pVFile;
   546    pVFile->nRef++;
   547    pFile->pMethods = &VHandleMethods;
   548    if( pOutFlags ) *pOutFlags = openFlags;
   549    return SQLITE_OK;
   550  }
   551  
   552  /*
   553  ** Delete a file by name
   554  */
   555  static int inmemDelete(
   556    sqlite3_vfs *pVfs,
   557    const char *zFilename,
   558    int syncdir
   559  ){
   560    VFile *pVFile = findVFile(zFilename);
   561    if( pVFile==0 ) return SQLITE_OK;
   562    if( pVFile->nRef==0 ){
   563      free(pVFile->zFilename);
   564      pVFile->zFilename = 0;
   565      pVFile->sz = -1;
   566      free(pVFile->a);
   567      pVFile->a = 0;
   568      return SQLITE_OK;
   569    }
   570    return SQLITE_IOERR_DELETE;
   571  }
   572  
   573  /* Check for the existance of a file
   574  */
   575  static int inmemAccess(
   576    sqlite3_vfs *pVfs,
   577    const char *zFilename,
   578    int flags,
   579    int *pResOut
   580  ){
   581    VFile *pVFile = findVFile(zFilename);
   582    *pResOut =  pVFile!=0;
   583    return SQLITE_OK;
   584  }
   585  
   586  /* Get the canonical pathname for a file
   587  */
   588  static int inmemFullPathname(
   589    sqlite3_vfs *pVfs,
   590    const char *zFilename,
   591    int nOut,
   592    char *zOut
   593  ){
   594    sqlite3_snprintf(nOut, zOut, "%s", zFilename);
   595    return SQLITE_OK;
   596  }
   597  
   598  /* Always use the same random see, for repeatability.
   599  */
   600  static int inmemRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
   601    memset(zBuf, 0, nBuf);
   602    memcpy(zBuf, &g.uRandom, nBuf<sizeof(g.uRandom) ? nBuf : sizeof(g.uRandom));
   603    return nBuf;
   604  }
   605  
   606  /*
   607  ** Register the VFS that reads from the g.aFile[] set of files.
   608  */
   609  static void inmemVfsRegister(int makeDefault){
   610    static sqlite3_vfs inmemVfs;
   611    sqlite3_vfs *pDefault = sqlite3_vfs_find(0);
   612    inmemVfs.iVersion = 3;
   613    inmemVfs.szOsFile = sizeof(VHandle);
   614    inmemVfs.mxPathname = 200;
   615    inmemVfs.zName = "inmem";
   616    inmemVfs.xOpen = inmemOpen;
   617    inmemVfs.xDelete = inmemDelete;
   618    inmemVfs.xAccess = inmemAccess;
   619    inmemVfs.xFullPathname = inmemFullPathname;
   620    inmemVfs.xRandomness = inmemRandomness;
   621    inmemVfs.xSleep = pDefault->xSleep;
   622    inmemVfs.xCurrentTimeInt64 = pDefault->xCurrentTimeInt64;
   623    sqlite3_vfs_register(&inmemVfs, makeDefault);
   624  };
   625  
   626  /*
   627  ** Allowed values for the runFlags parameter to runSql()
   628  */
   629  #define SQL_TRACE  0x0001     /* Print each SQL statement as it is prepared */
   630  #define SQL_OUTPUT 0x0002     /* Show the SQL output */
   631  
   632  /*
   633  ** Run multiple commands of SQL.  Similar to sqlite3_exec(), but does not
   634  ** stop if an error is encountered.
   635  */
   636  static void runSql(sqlite3 *db, const char *zSql, unsigned  runFlags){
   637    const char *zMore;
   638    sqlite3_stmt *pStmt;
   639  
   640    while( zSql && zSql[0] ){
   641      zMore = 0;
   642      pStmt = 0;
   643      sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zMore);
   644      if( zMore==zSql ) break;
   645      if( runFlags & SQL_TRACE ){
   646        const char *z = zSql;
   647        int n;
   648        while( z<zMore && ISSPACE(z[0]) ) z++;
   649        n = (int)(zMore - z);
   650        while( n>0 && ISSPACE(z[n-1]) ) n--;
   651        if( n==0 ) break;
   652        if( pStmt==0 ){
   653          printf("TRACE: %.*s (error: %s)\n", n, z, sqlite3_errmsg(db));
   654        }else{
   655          printf("TRACE: %.*s\n", n, z);
   656        }
   657      }
   658      zSql = zMore;
   659      if( pStmt ){
   660        if( (runFlags & SQL_OUTPUT)==0 ){
   661          while( SQLITE_ROW==sqlite3_step(pStmt) ){}
   662        }else{
   663          int nCol = -1;
   664          while( SQLITE_ROW==sqlite3_step(pStmt) ){
   665            int i;
   666            if( nCol<0 ){
   667              nCol = sqlite3_column_count(pStmt);
   668            }else if( nCol>0 ){
   669              printf("--------------------------------------------\n");
   670            }
   671            for(i=0; i<nCol; i++){
   672              int eType = sqlite3_column_type(pStmt,i);
   673              printf("%s = ", sqlite3_column_name(pStmt,i));
   674              switch( eType ){
   675                case SQLITE_NULL: {
   676                  printf("NULL\n");
   677                  break;
   678                }
   679                case SQLITE_INTEGER: {
   680                  printf("INT %s\n", sqlite3_column_text(pStmt,i));
   681                  break;
   682                }
   683                case SQLITE_FLOAT: {
   684                  printf("FLOAT %s\n", sqlite3_column_text(pStmt,i));
   685                  break;
   686                }
   687                case SQLITE_TEXT: {
   688                  printf("TEXT [%s]\n", sqlite3_column_text(pStmt,i));
   689                  break;
   690                }
   691                case SQLITE_BLOB: {
   692                  printf("BLOB (%d bytes)\n", sqlite3_column_bytes(pStmt,i));
   693                  break;
   694                }
   695              }
   696            }
   697          }
   698        }         
   699        sqlite3_finalize(pStmt);
   700      }
   701    }
   702  }
   703  
   704  /*
   705  ** Rebuild the database file.
   706  **
   707  **    (1)  Remove duplicate entries
   708  **    (2)  Put all entries in order
   709  **    (3)  Vacuum
   710  */
   711  static void rebuild_database(sqlite3 *db){
   712    int rc;
   713    rc = sqlite3_exec(db, 
   714       "BEGIN;\n"
   715       "CREATE TEMP TABLE dbx AS SELECT DISTINCT dbcontent FROM db;\n"
   716       "DELETE FROM db;\n"
   717       "INSERT INTO db(dbid, dbcontent) SELECT NULL, dbcontent FROM dbx ORDER BY 2;\n"
   718       "DROP TABLE dbx;\n"
   719       "CREATE TEMP TABLE sx AS SELECT DISTINCT sqltext FROM xsql;\n"
   720       "DELETE FROM xsql;\n"
   721       "INSERT INTO xsql(sqlid,sqltext) SELECT NULL, sqltext FROM sx ORDER BY 2;\n"
   722       "DROP TABLE sx;\n"
   723       "COMMIT;\n"
   724       "PRAGMA page_size=1024;\n"
   725       "VACUUM;\n", 0, 0, 0);
   726    if( rc ) fatalError("cannot rebuild: %s", sqlite3_errmsg(db));
   727  }
   728  
   729  /*
   730  ** Return the value of a hexadecimal digit.  Return -1 if the input
   731  ** is not a hex digit.
   732  */
   733  static int hexDigitValue(char c){
   734    if( c>='0' && c<='9' ) return c - '0';
   735    if( c>='a' && c<='f' ) return c - 'a' + 10;
   736    if( c>='A' && c<='F' ) return c - 'A' + 10;
   737    return -1;
   738  }
   739  
   740  /*
   741  ** Interpret zArg as an integer value, possibly with suffixes.
   742  */
   743  static int integerValue(const char *zArg){
   744    sqlite3_int64 v = 0;
   745    static const struct { char *zSuffix; int iMult; } aMult[] = {
   746      { "KiB", 1024 },
   747      { "MiB", 1024*1024 },
   748      { "GiB", 1024*1024*1024 },
   749      { "KB",  1000 },
   750      { "MB",  1000000 },
   751      { "GB",  1000000000 },
   752      { "K",   1000 },
   753      { "M",   1000000 },
   754      { "G",   1000000000 },
   755    };
   756    int i;
   757    int isNeg = 0;
   758    if( zArg[0]=='-' ){
   759      isNeg = 1;
   760      zArg++;
   761    }else if( zArg[0]=='+' ){
   762      zArg++;
   763    }
   764    if( zArg[0]=='0' && zArg[1]=='x' ){
   765      int x;
   766      zArg += 2;
   767      while( (x = hexDigitValue(zArg[0]))>=0 ){
   768        v = (v<<4) + x;
   769        zArg++;
   770      }
   771    }else{
   772      while( ISDIGIT(zArg[0]) ){
   773        v = v*10 + zArg[0] - '0';
   774        zArg++;
   775      }
   776    }
   777    for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){
   778      if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
   779        v *= aMult[i].iMult;
   780        break;
   781      }
   782    }
   783    if( v>0x7fffffff ) fatalError("parameter too large - max 2147483648");
   784    return (int)(isNeg? -v : v);
   785  }
   786  
   787  /*
   788  ** Print sketchy documentation for this utility program
   789  */
   790  static void showHelp(void){
   791    printf("Usage: %s [options] SOURCE-DB ?ARGS...?\n", g.zArgv0);
   792    printf(
   793  "Read databases and SQL scripts from SOURCE-DB and execute each script against\n"
   794  "each database, checking for crashes and memory leaks.\n"
   795  "Options:\n"
   796  "  --cell-size-check    Set the PRAGMA cell_size_check=ON\n"
   797  "  --dbid N             Use only the database where dbid=N\n"
   798  "  --export-db DIR      Write databases to files(s) in DIR. Works with --dbid\n"
   799  "  --export-sql DIR     Write SQL to file(s) in DIR. Also works with --sqlid\n"
   800  "  --help               Show this help text\n"
   801  "  -q|--quiet           Reduced output\n"
   802  "  --limit-mem N        Limit memory used by test SQLite instance to N bytes\n"
   803  "  --limit-vdbe         Panic if any test runs for more than 100,000 cycles\n"
   804  "  --load-sql ARGS...   Load SQL scripts fro files into SOURCE-DB\n"
   805  "  --load-db ARGS...    Load template databases from files into SOURCE_DB\n"
   806  "  -m TEXT              Add a description to the database\n"
   807  "  --native-vfs         Use the native VFS for initially empty database files\n"
   808  "  --native-malloc      Turn off MEMSYS3/5 and Lookaside\n"
   809  "  --oss-fuzz           Enable OSS-FUZZ testing\n"
   810  "  --prng-seed N        Seed value for the PRGN inside of SQLite\n"
   811  "  --rebuild            Rebuild and vacuum the database file\n"
   812  "  --result-trace       Show the results of each SQL command\n"
   813  "  --sqlid N            Use only SQL where sqlid=N\n"
   814  "  --timeout N          Abort if any single test needs more than N seconds\n"
   815  "  -v|--verbose         Increased output.  Repeat for more output.\n"
   816    );
   817  }
   818  
   819  int main(int argc, char **argv){
   820    sqlite3_int64 iBegin;        /* Start time of this program */
   821    int quietFlag = 0;           /* True if --quiet or -q */
   822    int verboseFlag = 0;         /* True if --verbose or -v */
   823    char *zInsSql = 0;           /* SQL statement for --load-db or --load-sql */
   824    int iFirstInsArg = 0;        /* First argv[] to use for --load-db or --load-sql */
   825    sqlite3 *db = 0;             /* The open database connection */
   826    sqlite3_stmt *pStmt;         /* A prepared statement */
   827    int rc;                      /* Result code from SQLite interface calls */
   828    Blob *pSql;                  /* For looping over SQL scripts */
   829    Blob *pDb;                   /* For looping over template databases */
   830    int i;                       /* Loop index for the argv[] loop */
   831    int onlySqlid = -1;          /* --sqlid */
   832    int onlyDbid = -1;           /* --dbid */
   833    int nativeFlag = 0;          /* --native-vfs */
   834    int rebuildFlag = 0;         /* --rebuild */
   835    int vdbeLimitFlag = 0;       /* --limit-vdbe */
   836    int timeoutTest = 0;         /* undocumented --timeout-test flag */
   837    int runFlags = 0;            /* Flags sent to runSql() */
   838    char *zMsg = 0;              /* Add this message */
   839    int nSrcDb = 0;              /* Number of source databases */
   840    char **azSrcDb = 0;          /* Array of source database names */
   841    int iSrcDb;                  /* Loop over all source databases */
   842    int nTest = 0;               /* Total number of tests performed */
   843    char *zDbName = "";          /* Appreviated name of a source database */
   844    const char *zFailCode = 0;   /* Value of the TEST_FAILURE environment variable */
   845    int cellSzCkFlag = 0;        /* --cell-size-check */
   846    int sqlFuzz = 0;             /* True for SQL fuzz testing. False for DB fuzz */
   847    int iTimeout = 120;          /* Default 120-second timeout */
   848    int nMem = 0;                /* Memory limit */
   849    int nMemThisDb = 0;          /* Memory limit set by the CONFIG table */
   850    char *zExpDb = 0;            /* Write Databases to files in this directory */
   851    char *zExpSql = 0;           /* Write SQL to files in this directory */
   852    void *pHeap = 0;             /* Heap for use by SQLite */
   853    int ossFuzz = 0;             /* enable OSS-FUZZ testing */
   854    int ossFuzzThisDb = 0;       /* ossFuzz value for this particular database */
   855    int nativeMalloc = 0;        /* Turn off MEMSYS3/5 and lookaside if true */
   856    sqlite3_vfs *pDfltVfs;       /* The default VFS */
   857  
   858    iBegin = timeOfDay();
   859  #ifdef __unix__
   860    signal(SIGALRM, timeoutHandler);
   861  #endif
   862    g.zArgv0 = argv[0];
   863    zFailCode = getenv("TEST_FAILURE");
   864    pDfltVfs = sqlite3_vfs_find(0);
   865    inmemVfsRegister(1);
   866    for(i=1; i<argc; i++){
   867      const char *z = argv[i];
   868      if( z[0]=='-' ){
   869        z++;
   870        if( z[0]=='-' ) z++;
   871        if( strcmp(z,"cell-size-check")==0 ){
   872          cellSzCkFlag = 1;
   873        }else
   874        if( strcmp(z,"dbid")==0 ){
   875          if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
   876          onlyDbid = integerValue(argv[++i]);
   877        }else
   878        if( strcmp(z,"export-db")==0 ){
   879          if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
   880          zExpDb = argv[++i];
   881        }else
   882        if( strcmp(z,"export-sql")==0 ){
   883          if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
   884          zExpSql = argv[++i];
   885        }else
   886        if( strcmp(z,"help")==0 ){
   887          showHelp();
   888          return 0;
   889        }else
   890        if( strcmp(z,"limit-mem")==0 ){
   891  #if !defined(SQLITE_ENABLE_MEMSYS3) && !defined(SQLITE_ENABLE_MEMSYS5)
   892          fatalError("the %s option requires -DSQLITE_ENABLE_MEMSYS5 or _MEMSYS3",
   893                     argv[i]);
   894  #else
   895          if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
   896          nMem = integerValue(argv[++i]);
   897  #endif
   898        }else
   899        if( strcmp(z,"limit-vdbe")==0 ){
   900          vdbeLimitFlag = 1;
   901        }else
   902        if( strcmp(z,"load-sql")==0 ){
   903          zInsSql = "INSERT INTO xsql(sqltext) VALUES(CAST(readfile(?1) AS text))";
   904          iFirstInsArg = i+1;
   905          break;
   906        }else
   907        if( strcmp(z,"load-db")==0 ){
   908          zInsSql = "INSERT INTO db(dbcontent) VALUES(readfile(?1))";
   909          iFirstInsArg = i+1;
   910          break;
   911        }else
   912        if( strcmp(z,"m")==0 ){
   913          if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
   914          zMsg = argv[++i];
   915        }else
   916        if( strcmp(z,"native-malloc")==0 ){
   917          nativeMalloc = 1;
   918        }else
   919        if( strcmp(z,"native-vfs")==0 ){
   920          nativeFlag = 1;
   921        }else
   922        if( strcmp(z,"oss-fuzz")==0 ){
   923          ossFuzz = 1;
   924        }else
   925        if( strcmp(z,"prng-seed")==0 ){
   926          if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
   927          g.uRandom = atoi(argv[++i]);
   928        }else
   929        if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
   930          quietFlag = 1;
   931          verboseFlag = 0;
   932        }else
   933        if( strcmp(z,"rebuild")==0 ){
   934          rebuildFlag = 1;
   935        }else
   936        if( strcmp(z,"result-trace")==0 ){
   937          runFlags |= SQL_OUTPUT;
   938        }else
   939        if( strcmp(z,"sqlid")==0 ){
   940          if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
   941          onlySqlid = integerValue(argv[++i]);
   942        }else
   943        if( strcmp(z,"timeout")==0 ){
   944          if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
   945          iTimeout = integerValue(argv[++i]);
   946        }else
   947        if( strcmp(z,"timeout-test")==0 ){
   948          timeoutTest = 1;
   949  #ifndef __unix__
   950          fatalError("timeout is not available on non-unix systems");
   951  #endif
   952        }else
   953        if( strcmp(z,"verbose")==0 || strcmp(z,"v")==0 ){
   954          quietFlag = 0;
   955          verboseFlag++;
   956          if( verboseFlag>1 ) runFlags |= SQL_TRACE;
   957        }else
   958        {
   959          fatalError("unknown option: %s", argv[i]);
   960        }
   961      }else{
   962        nSrcDb++;
   963        azSrcDb = safe_realloc(azSrcDb, nSrcDb*sizeof(azSrcDb[0]));
   964        azSrcDb[nSrcDb-1] = argv[i];
   965      }
   966    }
   967    if( nSrcDb==0 ) fatalError("no source database specified");
   968    if( nSrcDb>1 ){
   969      if( zMsg ){
   970        fatalError("cannot change the description of more than one database");
   971      }
   972      if( zInsSql ){
   973        fatalError("cannot import into more than one database");
   974      }
   975    }
   976  
   977    /* Process each source database separately */
   978    for(iSrcDb=0; iSrcDb<nSrcDb; iSrcDb++){
   979      rc = sqlite3_open_v2(azSrcDb[iSrcDb], &db,
   980                           SQLITE_OPEN_READWRITE, pDfltVfs->zName);
   981      if( rc ){
   982        fatalError("cannot open source database %s - %s",
   983        azSrcDb[iSrcDb], sqlite3_errmsg(db));
   984      }
   985      rc = sqlite3_exec(db,
   986         "CREATE TABLE IF NOT EXISTS db(\n"
   987         "  dbid INTEGER PRIMARY KEY, -- database id\n"
   988         "  dbcontent BLOB            -- database disk file image\n"
   989         ");\n"
   990         "CREATE TABLE IF NOT EXISTS xsql(\n"
   991         "  sqlid INTEGER PRIMARY KEY,   -- SQL script id\n"
   992         "  sqltext TEXT                 -- Text of SQL statements to run\n"
   993         ");"
   994         "CREATE TABLE IF NOT EXISTS readme(\n"
   995         "  msg TEXT -- Human-readable description of this file\n"
   996         ");", 0, 0, 0);
   997      if( rc ) fatalError("cannot create schema: %s", sqlite3_errmsg(db));
   998      if( zMsg ){
   999        char *zSql;
  1000        zSql = sqlite3_mprintf(
  1001                 "DELETE FROM readme; INSERT INTO readme(msg) VALUES(%Q)", zMsg);
  1002        rc = sqlite3_exec(db, zSql, 0, 0, 0);
  1003        sqlite3_free(zSql);
  1004        if( rc ) fatalError("cannot change description: %s", sqlite3_errmsg(db));
  1005      }
  1006      ossFuzzThisDb = ossFuzz;
  1007  
  1008      /* If the CONFIG(name,value) table exists, read db-specific settings
  1009      ** from that table */
  1010      if( sqlite3_table_column_metadata(db,0,"config",0,0,0,0,0,0)==SQLITE_OK ){
  1011        rc = sqlite3_prepare_v2(db, "SELECT name, value FROM config", -1, &pStmt, 0);
  1012        if( rc ) fatalError("cannot prepare query of CONFIG table: %s",
  1013                            sqlite3_errmsg(db));
  1014        while( SQLITE_ROW==sqlite3_step(pStmt) ){
  1015          const char *zName = (const char *)sqlite3_column_text(pStmt,0);
  1016          if( zName==0 ) continue;
  1017          if( strcmp(zName, "oss-fuzz")==0 ){
  1018            ossFuzzThisDb = sqlite3_column_int(pStmt,1);
  1019            if( verboseFlag ) printf("Config: oss-fuzz=%d\n", ossFuzzThisDb);
  1020          }
  1021          if( strcmp(zName, "limit-mem")==0 && !nativeMalloc ){
  1022  #if !defined(SQLITE_ENABLE_MEMSYS3) && !defined(SQLITE_ENABLE_MEMSYS5)
  1023            fatalError("the limit-mem option requires -DSQLITE_ENABLE_MEMSYS5"
  1024                       " or _MEMSYS3");
  1025  #else
  1026            nMemThisDb = sqlite3_column_int(pStmt,1);
  1027            if( verboseFlag ) printf("Config: limit-mem=%d\n", nMemThisDb);
  1028  #endif
  1029          }
  1030        }
  1031        sqlite3_finalize(pStmt);
  1032      }
  1033  
  1034      if( zInsSql ){
  1035        sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
  1036                                readfileFunc, 0, 0);
  1037        rc = sqlite3_prepare_v2(db, zInsSql, -1, &pStmt, 0);
  1038        if( rc ) fatalError("cannot prepare statement [%s]: %s",
  1039                            zInsSql, sqlite3_errmsg(db));
  1040        rc = sqlite3_exec(db, "BEGIN", 0, 0, 0);
  1041        if( rc ) fatalError("cannot start a transaction");
  1042        for(i=iFirstInsArg; i<argc; i++){
  1043          sqlite3_bind_text(pStmt, 1, argv[i], -1, SQLITE_STATIC);
  1044          sqlite3_step(pStmt);
  1045          rc = sqlite3_reset(pStmt);
  1046          if( rc ) fatalError("insert failed for %s", argv[i]);
  1047        }
  1048        sqlite3_finalize(pStmt);
  1049        rc = sqlite3_exec(db, "COMMIT", 0, 0, 0);
  1050        if( rc ) fatalError("cannot commit the transaction: %s", sqlite3_errmsg(db));
  1051        rebuild_database(db);
  1052        sqlite3_close(db);
  1053        return 0;
  1054      }
  1055      rc = sqlite3_exec(db, "PRAGMA query_only=1;", 0, 0, 0);
  1056      if( rc ) fatalError("cannot set database to query-only");
  1057      if( zExpDb!=0 || zExpSql!=0 ){
  1058        sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
  1059                                writefileFunc, 0, 0);
  1060        if( zExpDb!=0 ){
  1061          const char *zExDb = 
  1062            "SELECT writefile(printf('%s/db%06d.db',?1,dbid),dbcontent),"
  1063            "       dbid, printf('%s/db%06d.db',?1,dbid), length(dbcontent)"
  1064            "  FROM db WHERE ?2<0 OR dbid=?2;";
  1065          rc = sqlite3_prepare_v2(db, zExDb, -1, &pStmt, 0);
  1066          if( rc ) fatalError("cannot prepare statement [%s]: %s",
  1067                              zExDb, sqlite3_errmsg(db));
  1068          sqlite3_bind_text64(pStmt, 1, zExpDb, strlen(zExpDb),
  1069                              SQLITE_STATIC, SQLITE_UTF8);
  1070          sqlite3_bind_int(pStmt, 2, onlyDbid);
  1071          while( sqlite3_step(pStmt)==SQLITE_ROW ){
  1072            printf("write db-%d (%d bytes) into %s\n",
  1073               sqlite3_column_int(pStmt,1),
  1074               sqlite3_column_int(pStmt,3),
  1075               sqlite3_column_text(pStmt,2));
  1076          }
  1077          sqlite3_finalize(pStmt);
  1078        }
  1079        if( zExpSql!=0 ){
  1080          const char *zExSql = 
  1081            "SELECT writefile(printf('%s/sql%06d.txt',?1,sqlid),sqltext),"
  1082            "       sqlid, printf('%s/sql%06d.txt',?1,sqlid), length(sqltext)"
  1083            "  FROM xsql WHERE ?2<0 OR sqlid=?2;";
  1084          rc = sqlite3_prepare_v2(db, zExSql, -1, &pStmt, 0);
  1085          if( rc ) fatalError("cannot prepare statement [%s]: %s",
  1086                              zExSql, sqlite3_errmsg(db));
  1087          sqlite3_bind_text64(pStmt, 1, zExpSql, strlen(zExpSql),
  1088                              SQLITE_STATIC, SQLITE_UTF8);
  1089          sqlite3_bind_int(pStmt, 2, onlySqlid);
  1090          while( sqlite3_step(pStmt)==SQLITE_ROW ){
  1091            printf("write sql-%d (%d bytes) into %s\n",
  1092               sqlite3_column_int(pStmt,1),
  1093               sqlite3_column_int(pStmt,3),
  1094               sqlite3_column_text(pStmt,2));
  1095          }
  1096          sqlite3_finalize(pStmt);
  1097        }
  1098        sqlite3_close(db);
  1099        return 0;
  1100      }
  1101    
  1102      /* Load all SQL script content and all initial database images from the
  1103      ** source db
  1104      */
  1105      blobListLoadFromDb(db, "SELECT sqlid, sqltext FROM xsql", onlySqlid,
  1106                             &g.nSql, &g.pFirstSql);
  1107      if( g.nSql==0 ) fatalError("need at least one SQL script");
  1108      blobListLoadFromDb(db, "SELECT dbid, dbcontent FROM db", onlyDbid,
  1109                         &g.nDb, &g.pFirstDb);
  1110      if( g.nDb==0 ){
  1111        g.pFirstDb = safe_realloc(0, sizeof(Blob));
  1112        memset(g.pFirstDb, 0, sizeof(Blob));
  1113        g.pFirstDb->id = 1;
  1114        g.pFirstDb->seq = 0;
  1115        g.nDb = 1;
  1116        sqlFuzz = 1;
  1117      }
  1118    
  1119      /* Print the description, if there is one */
  1120      if( !quietFlag ){
  1121        zDbName = azSrcDb[iSrcDb];
  1122        i = (int)strlen(zDbName) - 1;
  1123        while( i>0 && zDbName[i-1]!='/' && zDbName[i-1]!='\\' ){ i--; }
  1124        zDbName += i;
  1125        sqlite3_prepare_v2(db, "SELECT msg FROM readme", -1, &pStmt, 0);
  1126        if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
  1127          printf("%s: %s\n", zDbName, sqlite3_column_text(pStmt,0));
  1128        }
  1129        sqlite3_finalize(pStmt);
  1130      }
  1131  
  1132      /* Rebuild the database, if requested */
  1133      if( rebuildFlag ){
  1134        if( !quietFlag ){
  1135          printf("%s: rebuilding... ", zDbName);
  1136          fflush(stdout);
  1137        }
  1138        rebuild_database(db);
  1139        if( !quietFlag ) printf("done\n");
  1140      }
  1141    
  1142      /* Close the source database.  Verify that no SQLite memory allocations are
  1143      ** outstanding.
  1144      */
  1145      sqlite3_close(db);
  1146      if( sqlite3_memory_used()>0 ){
  1147        fatalError("SQLite has memory in use before the start of testing");
  1148      }
  1149  
  1150      /* Limit available memory, if requested */
  1151      sqlite3_shutdown();
  1152      if( nMemThisDb>0 && !nativeMalloc ){
  1153        pHeap = realloc(pHeap, nMemThisDb);
  1154        if( pHeap==0 ){
  1155          fatalError("failed to allocate %d bytes of heap memory", nMem);
  1156        }
  1157        sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nMemThisDb, 128);
  1158      }
  1159  
  1160      /* Disable lookaside with the --native-malloc option */
  1161      if( nativeMalloc ){
  1162        sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
  1163      }
  1164    
  1165      /* Reset the in-memory virtual filesystem */
  1166      formatVfs();
  1167      
  1168      /* Run a test using each SQL script against each database.
  1169      */
  1170      if( !verboseFlag && !quietFlag ) printf("%s:", zDbName);
  1171      for(pSql=g.pFirstSql; pSql; pSql=pSql->pNext){
  1172        for(pDb=g.pFirstDb; pDb; pDb=pDb->pNext){
  1173          int openFlags;
  1174          const char *zVfs = "inmem";
  1175          sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d,dbid=%d",
  1176                           pSql->id, pDb->id);
  1177          if( verboseFlag ){
  1178            printf("%s\n", g.zTestName);
  1179            fflush(stdout);
  1180          }else if( !quietFlag ){
  1181            static int prevAmt = -1;
  1182            int idx = pSql->seq*g.nDb + pDb->id - 1;
  1183            int amt = idx*10/(g.nDb*g.nSql);
  1184            if( amt!=prevAmt ){
  1185              printf(" %d%%", amt*10);
  1186              fflush(stdout);
  1187              prevAmt = amt;
  1188            }
  1189          }
  1190          createVFile("main.db", pDb->sz, pDb->a);
  1191          sqlite3_randomness(0,0);
  1192          if( ossFuzzThisDb ){
  1193  #ifndef SQLITE_OSS_FUZZ
  1194            fatalError("--oss-fuzz not supported: recompile with -DSQLITE_OSS_FUZZ");
  1195  #else
  1196            extern int LLVMFuzzerTestOneInput(const uint8_t*, size_t);
  1197            LLVMFuzzerTestOneInput((const uint8_t*)pSql->a, (size_t)pSql->sz);
  1198  #endif
  1199          }else{
  1200            openFlags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE;
  1201            if( nativeFlag && pDb->sz==0 ){
  1202              openFlags |= SQLITE_OPEN_MEMORY;
  1203              zVfs = 0;
  1204            }
  1205            rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs);
  1206            if( rc ) fatalError("cannot open inmem database");
  1207            sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 100000000);
  1208            sqlite3_limit(db, SQLITE_LIMIT_LIKE_PATTERN_LENGTH, 50);
  1209            if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags);
  1210            setAlarm(iTimeout);
  1211  #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  1212            if( sqlFuzz || vdbeLimitFlag ){
  1213              sqlite3_progress_handler(db, 100000, progressHandler, &vdbeLimitFlag);
  1214            }
  1215  #endif
  1216            do{
  1217              runSql(db, (char*)pSql->a, runFlags);
  1218            }while( timeoutTest );
  1219            setAlarm(0);
  1220            sqlite3_exec(db, "PRAGMA temp_store_directory=''", 0, 0, 0);
  1221            sqlite3_close(db);
  1222          }
  1223          if( sqlite3_memory_used()>0 ){
  1224             fatalError("memory leak: %lld bytes outstanding",
  1225                        sqlite3_memory_used());
  1226          }
  1227          reformatVfs();
  1228          nTest++;
  1229          g.zTestName[0] = 0;
  1230  
  1231          /* Simulate an error if the TEST_FAILURE environment variable is "5".
  1232          ** This is used to verify that automated test script really do spot
  1233          ** errors that occur in this test program.
  1234          */
  1235          if( zFailCode ){
  1236            if( zFailCode[0]=='5' && zFailCode[1]==0 ){
  1237              fatalError("simulated failure");
  1238            }else if( zFailCode[0]!=0 ){
  1239              /* If TEST_FAILURE is something other than 5, just exit the test
  1240              ** early */
  1241              printf("\nExit early due to TEST_FAILURE being set\n");
  1242              iSrcDb = nSrcDb-1;
  1243              goto sourcedb_cleanup;
  1244            }
  1245          }
  1246        }
  1247      }
  1248      if( !quietFlag && !verboseFlag ){
  1249        printf(" 100%% - %d tests\n", g.nDb*g.nSql);
  1250      }
  1251    
  1252      /* Clean up at the end of processing a single source database
  1253      */
  1254    sourcedb_cleanup:
  1255      blobListFree(g.pFirstSql);
  1256      blobListFree(g.pFirstDb);
  1257      reformatVfs();
  1258   
  1259    } /* End loop over all source databases */
  1260  
  1261    if( !quietFlag ){
  1262      sqlite3_int64 iElapse = timeOfDay() - iBegin;
  1263      printf("fuzzcheck: 0 errors out of %d tests in %d.%03d seconds\n"
  1264             "SQLite %s %s\n",
  1265             nTest, (int)(iElapse/1000), (int)(iElapse%1000),
  1266             sqlite3_libversion(), sqlite3_sourceid());
  1267    }
  1268    free(azSrcDb);
  1269    free(pHeap);
  1270    return 0;
  1271  }