Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Remove an assert ("assert( subpage>0 )") from btree.c that may not be true for a corrupt database. Also add comments and other assert() statements to btree.c function moveToRoot(). (CVS 6886) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
3151dab9c78106217ec80ebadc666dfd |
User & Date: | danielk1977 2009-07-13 09:41:45.000 |
Context
2009-07-13
| ||
11:22 | In sqlite3PagerWrite(), do not set the PGHDR_NEED_SYNC flag on a page if an IO error occured while attempting to journal it. (CVS 6887) (check-in: b9be365d85 user: danielk1977 tags: trunk) | |
09:41 | Remove an assert ("assert( subpage>0 )") from btree.c that may not be true for a corrupt database. Also add comments and other assert() statements to btree.c function moveToRoot(). (CVS 6886) (check-in: 3151dab9c7 user: danielk1977 tags: trunk) | |
07:30 | Remove a case from BtreeMovetoUnpacked() that is unreachable as of (6881). (CVS 6885) (check-in: 39ce2097da user: danielk1977 tags: trunk) | |
Changes
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* ** $Id: btree.c,v 1.684 2009/07/13 09:41:45 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ #include "btreeInt.h" |
︙ | ︙ | |||
3970 3971 3972 3973 3974 3975 3976 | releasePage(pCur->apPage[pCur->iPage]); pCur->iPage--; pCur->info.nSize = 0; pCur->validNKey = 0; } /* | | > > > > > > > > > > > > > > > > > > > | 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 | releasePage(pCur->apPage[pCur->iPage]); pCur->iPage--; pCur->info.nSize = 0; pCur->validNKey = 0; } /* ** Move the cursor to point to the root page of its b-tree structure. ** ** If the table has a virtual root page, then the cursor is moved to point ** to the virtual root page instead of the actual root page. A table has a ** virtual root page when the actual root page contains no cells and a ** single child page. This can only happen with the table rooted at page 1. ** ** If the b-tree structure is empty, the cursor state is set to ** CURSOR_INVALID. Otherwise, the cursor is set to point to the first ** cell located on the root (or virtual root) page and the cursor state ** is set to CURSOR_VALID. ** ** If this function returns successfully, it may be assumed that the ** page-header flags indicate that the [virtual] root-page is the expected ** kind of b-tree page (i.e. if when opening the cursor the caller did not ** specify a KeyInfo structure the flags byte is set to 0x05 or 0x0D, ** indicating a table b-tree, or if the caller did specify a KeyInfo ** structure the flags byte is set to 0x02 or 0x0A, indicating an index ** b-tree). */ static int moveToRoot(BtCursor *pCur){ MemPage *pRoot; int rc = SQLITE_OK; Btree *p = pCur->pBtree; BtShared *pBt = p->pBt; assert( cursorHoldsMutex(pCur) ); assert( CURSOR_INVALID < CURSOR_REQUIRESEEK ); assert( CURSOR_VALID < CURSOR_REQUIRESEEK ); assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); if( pCur->eState>=CURSOR_REQUIRESEEK ){ if( pCur->eState==CURSOR_FAULT ){ assert( pCur->skip!=SQLITE_OK ); return pCur->skip; } sqlite3BtreeClearCursor(pCur); } if( pCur->iPage>=0 ){ int i; |
︙ | ︙ | |||
4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 | ** return an SQLITE_CORRUPT error. */ assert( pCur->apPage[0]->intKey==1 || pCur->apPage[0]->intKey==0 ); if( (pCur->pKeyInfo==0)!=pCur->apPage[0]->intKey ){ return SQLITE_CORRUPT_BKPT; } } pRoot = pCur->apPage[0]; assert( pRoot->pgno==pCur->pgnoRoot ); pCur->aiIdx[0] = 0; pCur->info.nSize = 0; pCur->atLast = 0; pCur->validNKey = 0; if( pRoot->nCell==0 && !pRoot->leaf ){ Pgno subpage; if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT; | > > > > > > > > < < | 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 | ** return an SQLITE_CORRUPT error. */ assert( pCur->apPage[0]->intKey==1 || pCur->apPage[0]->intKey==0 ); if( (pCur->pKeyInfo==0)!=pCur->apPage[0]->intKey ){ return SQLITE_CORRUPT_BKPT; } } /* Assert that the root page is of the correct type. This must be the ** case as the call to this function that loaded the root-page (either ** this call or a previous invocation) would have detected corruption ** if the assumption were not true, and it is not possible for the flags ** byte to have been modified while this cursor is holding a reference ** to the page. */ pRoot = pCur->apPage[0]; assert( pRoot->pgno==pCur->pgnoRoot ); assert( pRoot->isInit && (pCur->pKeyInfo==0)==pRoot->intKey ); pCur->aiIdx[0] = 0; pCur->info.nSize = 0; pCur->atLast = 0; pCur->validNKey = 0; if( pRoot->nCell==0 && !pRoot->leaf ){ Pgno subpage; if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT; subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]); pCur->eState = CURSOR_VALID; rc = moveToChild(pCur, subpage); }else{ pCur->eState = ((pRoot->nCell>0)?CURSOR_VALID:CURSOR_INVALID); } return rc; } |
︙ | ︙ | |||
6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 | return rc; } assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) ); pPage = pCur->apPage[pCur->iPage]; assert( pPage->intKey || nKey>=0 ); assert( pPage->leaf || !pPage->intKey ); TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n", pCur->pgnoRoot, nKey, nData, pPage->pgno, loc==0 ? "overwrite" : "new entry")); assert( pPage->isInit ); allocateTempSpace(pBt); newCell = pBt->pTmpSpace; if( newCell==0 ) return SQLITE_NOMEM; | > | 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 | return rc; } assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) ); pPage = pCur->apPage[pCur->iPage]; assert( pPage->intKey || nKey>=0 ); assert( pPage->leaf || !pPage->intKey ); TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n", pCur->pgnoRoot, nKey, nData, pPage->pgno, loc==0 ? "overwrite" : "new entry")); assert( pPage->isInit ); allocateTempSpace(pBt); newCell = pBt->pTmpSpace; if( newCell==0 ) return SQLITE_NOMEM; |
︙ | ︙ |
Changes to test/corrupt.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests to make sure SQLite does not crash or # segfault if it sees a corrupt database file. # | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests to make sure SQLite does not crash or # segfault if it sees a corrupt database file. # # $Id: corrupt.test,v 1.12 2009/07/13 09:41:45 danielk1977 Exp $ catch {file delete -force test.db test.db-journal test.bu} set testdir [file dirname $argv0] source $testdir/tester.tcl # Construct a large database for testing. |
︙ | ︙ | |||
202 203 204 205 206 207 208 209 | # This will fail, as the block modified the database image so that the # child page of the deleted cell is from a table (intkey) b-tree, not an # index b-tree as expected. At one point this was causing an assert() # to fail. catchsql { DELETE FROM t1 WHERE rowid = 3 } } {1 {database disk image is malformed}} finish_test | > > > > > > > > > > > > > > > > > > > > | 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 | # This will fail, as the block modified the database image so that the # child page of the deleted cell is from a table (intkey) b-tree, not an # index b-tree as expected. At one point this was causing an assert() # to fail. catchsql { DELETE FROM t1 WHERE rowid = 3 } } {1 {database disk image is malformed}} do_test corrupt-5.1 { db close file delete -force test.db test.db-journal sqlite3 db test.db execsql { PRAGMA page_size = 1024 } set ct "CREATE TABLE t1(c0 " set i 0 while {[string length $ct] < 950} { append ct ", c[incr i]" } append ct ")" execsql $ct } {} do_test corrupt-5.2 { db close hexio_write test.db 108 00000000 sqlite3 db test.db catchsql { SELECT * FROM sqlite_master } } {1 {database disk image is malformed}} finish_test |