/ Check-in [ea5e0b74]
Login

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

Overview
Comment:Add fault-injection tests for the code in test_stat.c.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ea5e0b74c997492025225cd86e65e8a8c86ca4a0
User & Date: dan 2015-04-27 19:53:55
Context
2015-04-28
00:53
Add a TCL script that can be run to generate the fuzzdata1.txt file. check-in: fdc79fd1 user: drh tags: trunk
2015-04-27
19:53
Add fault-injection tests for the code in test_stat.c. check-in: ea5e0b74 user: dan tags: trunk
15:08
Update the fuzzer test data after having run it through afl-cmin to remove redundant test cases. check-in: 8134d41b user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/test_stat.c.

   136    136   static int statConnect(
   137    137     sqlite3 *db,
   138    138     void *pAux,
   139    139     int argc, const char *const*argv,
   140    140     sqlite3_vtab **ppVtab,
   141    141     char **pzErr
   142    142   ){
   143         -  StatTable *pTab;
          143  +  StatTable *pTab = 0;
          144  +  int rc = SQLITE_OK;
   144    145   
   145         -  pTab = (StatTable *)sqlite3_malloc(sizeof(StatTable));
   146         -  memset(pTab, 0, sizeof(StatTable));
   147         -  pTab->db = db;
          146  +  rc = sqlite3_declare_vtab(db, VTAB_SCHEMA);
          147  +  if( rc==SQLITE_OK ){
          148  +    pTab = (StatTable *)sqlite3_malloc(sizeof(StatTable));
          149  +    if( pTab==0 ) rc = SQLITE_NOMEM;
          150  +  }
   148    151   
   149         -  sqlite3_declare_vtab(db, VTAB_SCHEMA);
   150         -  *ppVtab = &pTab->base;
   151         -  return SQLITE_OK;
          152  +  assert( rc==SQLITE_OK || pTab==0 );
          153  +  if( rc==SQLITE_OK ){
          154  +    memset(pTab, 0, sizeof(StatTable));
          155  +    pTab->db = db;
          156  +  }
          157  +
          158  +  *ppVtab = (sqlite3_vtab*)pTab;
          159  +  return rc;
   152    160   }
   153    161   
   154    162   /*
   155    163   ** Disconnect from or destroy a statvfs virtual table.
   156    164   */
   157    165   static int statDisconnect(sqlite3_vtab *pVtab){
   158    166     sqlite3_free(pVtab);
................................................................................
   192    200   */
   193    201   static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
   194    202     StatTable *pTab = (StatTable *)pVTab;
   195    203     StatCursor *pCsr;
   196    204     int rc;
   197    205   
   198    206     pCsr = (StatCursor *)sqlite3_malloc(sizeof(StatCursor));
   199         -  memset(pCsr, 0, sizeof(StatCursor));
   200         -  pCsr->base.pVtab = pVTab;
          207  +  if( pCsr==0 ){
          208  +    rc = SQLITE_NOMEM;
          209  +  }else{
          210  +    memset(pCsr, 0, sizeof(StatCursor));
          211  +    pCsr->base.pVtab = pVTab;
   201    212   
   202         -  rc = sqlite3_prepare_v2(pTab->db, 
   203         -      "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
   204         -      "  UNION ALL  "
   205         -      "SELECT name, rootpage, type FROM sqlite_master WHERE rootpage!=0"
   206         -      "  ORDER BY name", -1,
   207         -      &pCsr->pStmt, 0
   208         -  );
   209         -  if( rc!=SQLITE_OK ){
   210         -    sqlite3_free(pCsr);
   211         -    return rc;
          213  +    rc = sqlite3_prepare_v2(pTab->db, 
          214  +        "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
          215  +        "  UNION ALL  "
          216  +        "SELECT name, rootpage, type FROM sqlite_master WHERE rootpage!=0"
          217  +        "  ORDER BY name", -1,
          218  +        &pCsr->pStmt, 0
          219  +        );
          220  +    if( rc!=SQLITE_OK ){
          221  +      sqlite3_free(pCsr);
          222  +      pCsr = 0;
          223  +    }
   212    224     }
   213    225   
   214    226     *ppCursor = (sqlite3_vtab_cursor *)pCsr;
   215         -  return SQLITE_OK;
          227  +  return rc;
   216    228   }
   217    229   
   218    230   static void statClearPage(StatPage *p){
   219    231     int i;
   220         -  for(i=0; i<p->nCell; i++){
   221         -    sqlite3_free(p->aCell[i].aOvfl);
          232  +  if( p->aCell ){
          233  +    for(i=0; i<p->nCell; i++){
          234  +      sqlite3_free(p->aCell[i].aOvfl);
          235  +    }
          236  +    sqlite3_free(p->aCell);
   222    237     }
   223    238     sqlite3PagerUnref(p->pPg);
   224         -  sqlite3_free(p->aCell);
   225    239     sqlite3_free(p->zPath);
   226    240     memset(p, 0, sizeof(StatPage));
   227    241   }
   228    242   
   229    243   static void statResetCsr(StatCursor *pCsr){
   230    244     int i;
   231    245     sqlite3_reset(pCsr->pStmt);
................................................................................
   303    317       int i;                        /* Used to iterate through cells */
   304    318       int nUsable;                  /* Usable bytes per page */
   305    319   
   306    320       sqlite3BtreeEnter(pBt);
   307    321       nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
   308    322       sqlite3BtreeLeave(pBt);
   309    323       p->aCell = sqlite3_malloc((p->nCell+1) * sizeof(StatCell));
          324  +    if( p->aCell==0 ) return SQLITE_NOMEM;
   310    325       memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));
   311    326   
   312    327       for(i=0; i<p->nCell; i++){
   313    328         StatCell *pCell = &p->aCell[i];
   314    329   
   315    330         iOff = get2byte(&aData[nHdr+i*2]);
   316    331         if( !isLeaf ){
................................................................................
   335    350           assert( nLocal<=(nUsable-35) );
   336    351           if( nPayload>(u32)nLocal ){
   337    352             int j;
   338    353             int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
   339    354             pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
   340    355             pCell->nOvfl = nOvfl;
   341    356             pCell->aOvfl = sqlite3_malloc(sizeof(u32)*nOvfl);
          357  +          if( pCell->aOvfl==0 ) return SQLITE_NOMEM;
   342    358             pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
   343    359             for(j=1; j<nOvfl; j++){
   344    360               int rc;
   345    361               u32 iPrev = pCell->aOvfl[j-1];
   346    362               DbPage *pPg = 0;
   347    363               rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg);
   348    364               if( rc!=SQLITE_OK ){
................................................................................
   482    498     */
   483    499     if( rc==SQLITE_OK ){
   484    500       int i;
   485    501       StatPage *p = &pCsr->aPage[pCsr->iPage];
   486    502       pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
   487    503       pCsr->iPageno = p->iPgno;
   488    504   
   489         -    statDecodePage(pBt, p);
   490         -    statSizeAndOffset(pCsr);
   491         -
   492         -    switch( p->flags ){
   493         -      case 0x05:             /* table internal */
   494         -      case 0x02:             /* index internal */
   495         -        pCsr->zPagetype = "internal";
   496         -        break;
   497         -      case 0x0D:             /* table leaf */
   498         -      case 0x0A:             /* index leaf */
   499         -        pCsr->zPagetype = "leaf";
   500         -        break;
   501         -      default:
   502         -        pCsr->zPagetype = "corrupted";
   503         -        break;
   504         -    }
   505         -    pCsr->nCell = p->nCell;
   506         -    pCsr->nUnused = p->nUnused;
   507         -    pCsr->nMxPayload = p->nMxPayload;
   508         -    pCsr->zPath = sqlite3_mprintf("%s", p->zPath);
   509         -    nPayload = 0;
   510         -    for(i=0; i<p->nCell; i++){
   511         -      nPayload += p->aCell[i].nLocal;
   512         -    }
   513         -    pCsr->nPayload = nPayload;
          505  +    rc = statDecodePage(pBt, p);
          506  +    if( rc==SQLITE_OK ){
          507  +      statSizeAndOffset(pCsr);
          508  +
          509  +      switch( p->flags ){
          510  +        case 0x05:             /* table internal */
          511  +        case 0x02:             /* index internal */
          512  +          pCsr->zPagetype = "internal";
          513  +          break;
          514  +        case 0x0D:             /* table leaf */
          515  +        case 0x0A:             /* index leaf */
          516  +          pCsr->zPagetype = "leaf";
          517  +          break;
          518  +        default:
          519  +          pCsr->zPagetype = "corrupted";
          520  +          break;
          521  +      }
          522  +      pCsr->nCell = p->nCell;
          523  +      pCsr->nUnused = p->nUnused;
          524  +      pCsr->nMxPayload = p->nMxPayload;
          525  +      pCsr->zPath = sqlite3_mprintf("%s", p->zPath);
          526  +      nPayload = 0;
          527  +      for(i=0; i<p->nCell; i++){
          528  +        nPayload += p->aCell[i].nLocal;
          529  +      }
          530  +      pCsr->nPayload = nPayload;
          531  +    }
   514    532     }
   515    533   
   516    534     return rc;
   517    535   }
   518    536   
   519    537   static int statEof(sqlite3_vtab_cursor *pCursor){
   520    538     StatCursor *pCsr = (StatCursor *)pCursor;

Changes to src/vdbe.c.

  6103   6103   
  6104   6104       /* Initialize vdbe cursor object */
  6105   6105       pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
  6106   6106       if( pCur ){
  6107   6107         pCur->pVtabCursor = pVtabCursor;
  6108   6108         pVtab->nRef++;
  6109   6109       }else{
  6110         -      db->mallocFailed = 1;
         6110  +      assert( db->mallocFailed );
  6111   6111         pModule->xClose(pVtabCursor);
         6112  +      goto no_mem;
  6112   6113       }
  6113   6114     }
  6114   6115     break;
  6115   6116   }
  6116   6117   #endif /* SQLITE_OMIT_VIRTUALTABLE */
  6117   6118   
  6118   6119   #ifndef SQLITE_OMIT_VIRTUALTABLE

Added test/statfault.test.

            1  +# 2015 April 28
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +set testdir [file dirname $argv0]
           14  +source $testdir/tester.tcl
           15  +source $testdir/malloc_common.tcl
           16  +set testprefix statfault
           17  +
           18  +ifcapable !vtab||!compound {
           19  +  finish_test
           20  +  return
           21  +}
           22  +
           23  +register_dbstat_vtab db
           24  +do_execsql_test statfault-1 {
           25  +  CREATE TABLE t1(a, b UNIQUE);
           26  +  INSERT INTO t1 VALUES(1, randomblob(500));
           27  +  INSERT INTO t1 VALUES(randomblob(500), 1);
           28  +  INSERT INTO t1 VALUES(2, randomblob(250));
           29  +  INSERT INTO t1 VALUES(randomblob(250), 2);
           30  +  CREATE VIRTUAL TABLE sss USING dbstat;
           31  +} {}
           32  +faultsim_save_and_close
           33  +
           34  +do_faultsim_test 1 -faults * -prep {
           35  +  faultsim_restore_and_reopen
           36  +  register_dbstat_vtab db
           37  +  execsql { SELECT 1 FROM sqlite_master LIMIT 1 }
           38  +} -body {
           39  +  execsql { SELECT count(*) FROM sss }
           40  +} -test {
           41  +  faultsim_test_result {0 8} 
           42  +}
           43  +
           44  +
           45  +finish_test