SQLite

Check-in [ea5e0b74c9]
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
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ea5e0b74c997492025225cd86e65e8a8c86ca4a0
User & Date: dan 2015-04-27 19:53:55.422
Context
2015-04-28
00:53
Add a TCL script that can be run to generate the fuzzdata1.txt file. (check-in: fdc79fd14a user: drh tags: trunk)
2015-04-27
19:53
Add fault-injection tests for the code in test_stat.c. (check-in: ea5e0b74c9 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: 8134d41b96 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/test_stat.c.
136
137
138
139
140
141
142
143

144


145





146
147
148
149
150
151
152
153
154
155
156
157
158
static int statConnect(
  sqlite3 *db,
  void *pAux,
  int argc, const char *const*argv,
  sqlite3_vtab **ppVtab,
  char **pzErr
){
  StatTable *pTab;




  pTab = (StatTable *)sqlite3_malloc(sizeof(StatTable));





  memset(pTab, 0, sizeof(StatTable));
  pTab->db = db;

  sqlite3_declare_vtab(db, VTAB_SCHEMA);
  *ppVtab = &pTab->base;
  return SQLITE_OK;
}

/*
** Disconnect from or destroy a statvfs virtual table.
*/
static int statDisconnect(sqlite3_vtab *pVtab){
  sqlite3_free(pVtab);







|
>

>
>
|
>
>
>
>
>
|
|
|
|
|
|







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
static int statConnect(
  sqlite3 *db,
  void *pAux,
  int argc, const char *const*argv,
  sqlite3_vtab **ppVtab,
  char **pzErr
){
  StatTable *pTab = 0;
  int rc = SQLITE_OK;

  rc = sqlite3_declare_vtab(db, VTAB_SCHEMA);
  if( rc==SQLITE_OK ){
    pTab = (StatTable *)sqlite3_malloc(sizeof(StatTable));
    if( pTab==0 ) rc = SQLITE_NOMEM;
  }

  assert( rc==SQLITE_OK || pTab==0 );
  if( rc==SQLITE_OK ){
    memset(pTab, 0, sizeof(StatTable));
    pTab->db = db;
  }

  *ppVtab = (sqlite3_vtab*)pTab;
  return rc;
}

/*
** Disconnect from or destroy a statvfs virtual table.
*/
static int statDisconnect(sqlite3_vtab *pVtab){
  sqlite3_free(pVtab);
192
193
194
195
196
197
198



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219

220
221
222
223
224


225
226
227
228
229
230
231
*/
static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
  StatTable *pTab = (StatTable *)pVTab;
  StatCursor *pCsr;
  int rc;

  pCsr = (StatCursor *)sqlite3_malloc(sizeof(StatCursor));



  memset(pCsr, 0, sizeof(StatCursor));
  pCsr->base.pVtab = pVTab;

  rc = sqlite3_prepare_v2(pTab->db, 
      "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
      "  UNION ALL  "
      "SELECT name, rootpage, type FROM sqlite_master WHERE rootpage!=0"
      "  ORDER BY name", -1,
      &pCsr->pStmt, 0
  );
  if( rc!=SQLITE_OK ){
    sqlite3_free(pCsr);
    return rc;
  }


  *ppCursor = (sqlite3_vtab_cursor *)pCsr;
  return SQLITE_OK;
}

static void statClearPage(StatPage *p){
  int i;

  for(i=0; i<p->nCell; i++){
    sqlite3_free(p->aCell[i].aOvfl);
  }
  sqlite3PagerUnref(p->pPg);
  sqlite3_free(p->aCell);


  sqlite3_free(p->zPath);
  memset(p, 0, sizeof(StatPage));
}

static void statResetCsr(StatCursor *pCsr){
  int i;
  sqlite3_reset(pCsr->pStmt);







>
>
>
|
|

|
|
|
|
|
|
|
|
|
|
|
|
>

|




>
|
|
|
<
|
>
>







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243
244
245
*/
static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
  StatTable *pTab = (StatTable *)pVTab;
  StatCursor *pCsr;
  int rc;

  pCsr = (StatCursor *)sqlite3_malloc(sizeof(StatCursor));
  if( pCsr==0 ){
    rc = SQLITE_NOMEM;
  }else{
    memset(pCsr, 0, sizeof(StatCursor));
    pCsr->base.pVtab = pVTab;

    rc = sqlite3_prepare_v2(pTab->db, 
        "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
        "  UNION ALL  "
        "SELECT name, rootpage, type FROM sqlite_master WHERE rootpage!=0"
        "  ORDER BY name", -1,
        &pCsr->pStmt, 0
        );
    if( rc!=SQLITE_OK ){
      sqlite3_free(pCsr);
      pCsr = 0;
    }
  }

  *ppCursor = (sqlite3_vtab_cursor *)pCsr;
  return rc;
}

static void statClearPage(StatPage *p){
  int i;
  if( p->aCell ){
    for(i=0; i<p->nCell; i++){
      sqlite3_free(p->aCell[i].aOvfl);
    }

    sqlite3_free(p->aCell);
  }
  sqlite3PagerUnref(p->pPg);
  sqlite3_free(p->zPath);
  memset(p, 0, sizeof(StatPage));
}

static void statResetCsr(StatCursor *pCsr){
  int i;
  sqlite3_reset(pCsr->pStmt);
303
304
305
306
307
308
309

310
311
312
313
314
315
316
    int i;                        /* Used to iterate through cells */
    int nUsable;                  /* Usable bytes per page */

    sqlite3BtreeEnter(pBt);
    nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
    sqlite3BtreeLeave(pBt);
    p->aCell = sqlite3_malloc((p->nCell+1) * sizeof(StatCell));

    memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));

    for(i=0; i<p->nCell; i++){
      StatCell *pCell = &p->aCell[i];

      iOff = get2byte(&aData[nHdr+i*2]);
      if( !isLeaf ){







>







317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
    int i;                        /* Used to iterate through cells */
    int nUsable;                  /* Usable bytes per page */

    sqlite3BtreeEnter(pBt);
    nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
    sqlite3BtreeLeave(pBt);
    p->aCell = sqlite3_malloc((p->nCell+1) * sizeof(StatCell));
    if( p->aCell==0 ) return SQLITE_NOMEM;
    memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));

    for(i=0; i<p->nCell; i++){
      StatCell *pCell = &p->aCell[i];

      iOff = get2byte(&aData[nHdr+i*2]);
      if( !isLeaf ){
335
336
337
338
339
340
341

342
343
344
345
346
347
348
        assert( nLocal<=(nUsable-35) );
        if( nPayload>(u32)nLocal ){
          int j;
          int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
          pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
          pCell->nOvfl = nOvfl;
          pCell->aOvfl = sqlite3_malloc(sizeof(u32)*nOvfl);

          pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
          for(j=1; j<nOvfl; j++){
            int rc;
            u32 iPrev = pCell->aOvfl[j-1];
            DbPage *pPg = 0;
            rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg);
            if( rc!=SQLITE_OK ){







>







350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
        assert( nLocal<=(nUsable-35) );
        if( nPayload>(u32)nLocal ){
          int j;
          int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
          pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
          pCell->nOvfl = nOvfl;
          pCell->aOvfl = sqlite3_malloc(sizeof(u32)*nOvfl);
          if( pCell->aOvfl==0 ) return SQLITE_NOMEM;
          pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
          for(j=1; j<nOvfl; j++){
            int rc;
            u32 iPrev = pCell->aOvfl[j-1];
            DbPage *pPg = 0;
            rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg);
            if( rc!=SQLITE_OK ){
482
483
484
485
486
487
488
489

490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513

514
515
516
517
518
519
520
  */
  if( rc==SQLITE_OK ){
    int i;
    StatPage *p = &pCsr->aPage[pCsr->iPage];
    pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
    pCsr->iPageno = p->iPgno;

    statDecodePage(pBt, p);

    statSizeAndOffset(pCsr);

    switch( p->flags ){
      case 0x05:             /* table internal */
      case 0x02:             /* index internal */
        pCsr->zPagetype = "internal";
        break;
      case 0x0D:             /* table leaf */
      case 0x0A:             /* index leaf */
        pCsr->zPagetype = "leaf";
        break;
      default:
        pCsr->zPagetype = "corrupted";
        break;
    }
    pCsr->nCell = p->nCell;
    pCsr->nUnused = p->nUnused;
    pCsr->nMxPayload = p->nMxPayload;
    pCsr->zPath = sqlite3_mprintf("%s", p->zPath);
    nPayload = 0;
    for(i=0; i<p->nCell; i++){
      nPayload += p->aCell[i].nLocal;
    }
    pCsr->nPayload = nPayload;

  }

  return rc;
}

static int statEof(sqlite3_vtab_cursor *pCursor){
  StatCursor *pCsr = (StatCursor *)pCursor;







|
>
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>







498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
  */
  if( rc==SQLITE_OK ){
    int i;
    StatPage *p = &pCsr->aPage[pCsr->iPage];
    pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
    pCsr->iPageno = p->iPgno;

    rc = statDecodePage(pBt, p);
    if( rc==SQLITE_OK ){
      statSizeAndOffset(pCsr);

      switch( p->flags ){
        case 0x05:             /* table internal */
        case 0x02:             /* index internal */
          pCsr->zPagetype = "internal";
          break;
        case 0x0D:             /* table leaf */
        case 0x0A:             /* index leaf */
          pCsr->zPagetype = "leaf";
          break;
        default:
          pCsr->zPagetype = "corrupted";
          break;
      }
      pCsr->nCell = p->nCell;
      pCsr->nUnused = p->nUnused;
      pCsr->nMxPayload = p->nMxPayload;
      pCsr->zPath = sqlite3_mprintf("%s", p->zPath);
      nPayload = 0;
      for(i=0; i<p->nCell; i++){
        nPayload += p->aCell[i].nLocal;
      }
      pCsr->nPayload = nPayload;
    }
  }

  return rc;
}

static int statEof(sqlite3_vtab_cursor *pCursor){
  StatCursor *pCsr = (StatCursor *)pCursor;
Changes to src/vdbe.c.
6103
6104
6105
6106
6107
6108
6109
6110
6111

6112
6113
6114
6115
6116
6117
6118

    /* Initialize vdbe cursor object */
    pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
    if( pCur ){
      pCur->pVtabCursor = pVtabCursor;
      pVtab->nRef++;
    }else{
      db->mallocFailed = 1;
      pModule->xClose(pVtabCursor);

    }
  }
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE







|

>







6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119

    /* Initialize vdbe cursor object */
    pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
    if( pCur ){
      pCur->pVtabCursor = pVtabCursor;
      pVtab->nRef++;
    }else{
      assert( db->mallocFailed );
      pModule->xClose(pVtabCursor);
      goto no_mem;
    }
  }
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
Added test/statfault.test.


























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 2015 April 28
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
set testprefix statfault

ifcapable !vtab||!compound {
  finish_test
  return
}

register_dbstat_vtab db
do_execsql_test statfault-1 {
  CREATE TABLE t1(a, b UNIQUE);
  INSERT INTO t1 VALUES(1, randomblob(500));
  INSERT INTO t1 VALUES(randomblob(500), 1);
  INSERT INTO t1 VALUES(2, randomblob(250));
  INSERT INTO t1 VALUES(randomblob(250), 2);
  CREATE VIRTUAL TABLE sss USING dbstat;
} {}
faultsim_save_and_close

do_faultsim_test 1 -faults * -prep {
  faultsim_restore_and_reopen
  register_dbstat_vtab db
  execsql { SELECT 1 FROM sqlite_master LIMIT 1 }
} -body {
  execsql { SELECT count(*) FROM sss }
} -test {
  faultsim_test_result {0 8} 
}


finish_test