/ Check-in [f3cd8cec]
Login

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

Overview
Comment:Merge the btree fixes out of trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | fuzzcheck
Files: files | file ages | folders
SHA1: f3cd8cecf4f7aa3429e3ebc90ed31c4e8fff7bc2
User & Date: drh 2015-05-25 19:37:17
Context
2015-05-25
21:59
Add the --native-vfs option on fuzzcheck. check-in: 12e95e3f user: drh tags: fuzzcheck
19:37
Merge the btree fixes out of trunk. check-in: f3cd8cec user: drh tags: fuzzcheck
19:35
Add the --dbid and --sqlid parameters to fuzzcheck. Other fuzzcheck fixes. check-in: 75ec9299 user: drh tags: fuzzcheck
19:24
Have the b-tree layer return SQLITE_CORRUPT to any attempt to open a cursor with a root page number less than 1. check-in: aa18c8e9 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  3884   3884     Btree *p,                                   /* The btree */
  3885   3885     int iTable,                                 /* Root page of table to open */
  3886   3886     int wrFlag,                                 /* 1 to write. 0 read-only */
  3887   3887     struct KeyInfo *pKeyInfo,                   /* First arg to xCompare() */
  3888   3888     BtCursor *pCur                              /* Write new cursor here */
  3889   3889   ){
  3890   3890     int rc;
  3891         -  sqlite3BtreeEnter(p);
  3892         -  rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
  3893         -  sqlite3BtreeLeave(p);
         3891  +  if( iTable<1 ){
         3892  +    rc = SQLITE_CORRUPT_BKPT;
         3893  +  }else{
         3894  +    sqlite3BtreeEnter(p);
         3895  +    rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
         3896  +    sqlite3BtreeLeave(p);
         3897  +  }
  3894   3898     return rc;
  3895   3899   }
  3896   3900   
  3897   3901   /*
  3898   3902   ** Return the size of a BtCursor object in bytes.
  3899   3903   **
  3900   3904   ** This interfaces is needed so that users of cursors can preallocate
................................................................................
  5746   5750     if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
  5747   5751       return SQLITE_CORRUPT_BKPT;  /* Cell extends past end of page */
  5748   5752     }
  5749   5753     ovflPgno = get4byte(&pCell[info.iOverflow]);
  5750   5754     assert( pBt->usableSize > 4 );
  5751   5755     ovflPageSize = pBt->usableSize - 4;
  5752   5756     nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
  5753         -  assert( ovflPgno==0 || nOvfl>0 );
         5757  +  assert( nOvfl>0 || 
         5758  +    (CORRUPT_DB && (info.nPayload + ovflPageSize)<ovflPageSize)
         5759  +  );
  5754   5760     while( nOvfl-- ){
  5755   5761       Pgno iNext = 0;
  5756   5762       MemPage *pOvfl = 0;
  5757   5763       if( ovflPgno<2 || ovflPgno>btreePagecount(pBt) ){
  5758   5764         /* 0 is not a legal page number and page 1 cannot be an 
  5759   5765         ** overflow page. Therefore if ovflPgno<2 or past the end of the 
  5760   5766         ** file the database must be corrupt. */
................................................................................
  6001   6007     u8 *ptr;        /* Used to move bytes around within data[] */
  6002   6008     int rc;         /* The return code */
  6003   6009     int hdr;        /* Beginning of the header.  0 most pages.  100 page 1 */
  6004   6010   
  6005   6011     if( *pRC ) return;
  6006   6012   
  6007   6013     assert( idx>=0 && idx<pPage->nCell );
  6008         -  assert( sz==cellSize(pPage, idx) );
         6014  +  assert( CORRUPT_DB || sz==cellSize(pPage, idx) );
  6009   6015     assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  6010   6016     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  6011   6017     data = pPage->aData;
  6012   6018     ptr = &pPage->aCellIdx[2*idx];
  6013   6019     pc = get2byte(ptr);
  6014   6020     hdr = pPage->hdrOffset;
  6015   6021     testcase( pc==get2byte(&data[hdr+5]) );

Changes to test/corruptI.test.

   179    179   } {12}
   180    180   
   181    181   do_test 5.3 {
   182    182     sqlite3 db test.db
   183    183     catchsql { CREATE TABLE tx(x); }
   184    184   } {1 {database disk image is malformed}}
   185    185   
          186  +
          187  +#-------------------------------------------------------------------------
          188  +# Set the payload size of a cell to just less than 2^32 bytes (not
          189  +# possible in an uncorrupted db). Then try to delete the cell. At one
          190  +# point this led to an integer overflow that caused an assert() to fail.
          191  +#
          192  +reset_db
          193  +do_execsql_test 6.0 {
          194  +  PRAGMA page_size = 512;
          195  +  CREATE TABLE t1(x);
          196  +  INSERT INTO t1 VALUES(zeroblob(300));
          197  +  INSERT INTO t1 VALUES(zeroblob(600));
          198  +} {}
          199  +do_test 6.1 {
          200  +  db close
          201  +  hexio_write test.db 616 EAFFFFFF0202
          202  +  sqlite3 db test.db
          203  +  breakpoint
          204  +  execsql { DELETE FROM t1 WHERE rowid=2 }
          205  +} {}
          206  +
          207  +#-------------------------------------------------------------------------
          208  +# See what happens if the sqlite_master entry associated with a PRIMARY
          209  +# KEY or UNIQUE index is removed. 
          210  +#
          211  +reset_db
          212  +do_execsql_test 7.0 {
          213  +  CREATE TABLE t1(x PRIMARY KEY, y);
          214  +  INSERT INTO t1 VALUES('a', 'A');
          215  +  INSERT INTO t1 VALUES('b', 'A');
          216  +  INSERT INTO t1 VALUES('c', 'A');
          217  +  SELECT name FROM sqlite_master;
          218  +} {t1 sqlite_autoindex_t1_1}
          219  +do_execsql_test 7.1 {
          220  +  PRAGMA writable_schema = 1;
          221  +  DELETE FROM sqlite_master WHERE name = 'sqlite_autoindex_t1_1';
          222  +}
          223  +do_test 7.2 {
          224  +  db close
          225  +  sqlite3 db test.db
          226  +  catchsql { UPDATE t1 SET x='d' AND y='D' WHERE rowid = 2 }
          227  +} {1 {database disk image is malformed}}
   186    228   
   187    229   finish_test