diff --git a/manifest b/manifest index 3c224d7e79..3226a1e874 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\scase\sfrom\sBtreeMovetoUnpacked()\sthat\sis\sunreachable\sas\sof\s(6881).\s(CVS\s6885) -D 2009-07-13T07:30:53 +C Remove\san\sassert\s("assert(\ssubpage>0\s)")\sfrom\sbtree.c\sthat\smay\snot\sbe\strue\sfor\sa\scorrupt\sdatabase.\sAlso\sadd\scomments\sand\sother\sassert()\sstatements\sto\sbtree.c\sfunction\smoveToRoot().\s(CVS\s6886) +D 2009-07-13T09:41:45 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in df9359da7a726ccb67a45db905c5447d5c00c6ef F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -106,7 +106,7 @@ F src/auth.c 802a9439dfa0b8c208b10055cba400e82ef18025 F src/backup.c 6f1c2d9862c8a3feb7739dfcca02c1f5352e37f3 F src/bitvec.c 0ef0651714728055d43de7a4cdd95e703fac0119 F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c -F src/btree.c 48825008514537420283ee9e51e0456263a39d2c +F src/btree.c a65e2050dacd0a5dc046c488f351588146fd5e3e F src/btree.h e53a10fd31d16c60a86f03c9467a6f470aa3683b F src/btreeInt.h a568bf057aa249eb06fd31358b4393a5ac88c118 F src/build.c 867028ee9f63f7bc8eb8d4a720bb98cf9b9a12b4 @@ -280,7 +280,7 @@ F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6 F test/colmeta.test 087c42997754b8c648819832241daf724f813322 F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b F test/conflict.test 0ed68b11f22721052d880ee80bd528a0e0828236 -F test/corrupt.test e940096bcfac0399d09c5351c0d6ea610477c08a +F test/corrupt.test 04e717ebb644f1b30b142cb5f30797747ef5f02f F test/corrupt2.test a571e30ea4e82318f319a24b6cc55935ce862079 F test/corrupt3.test 263e8bb04e2728df832fddf6973cf54c91db0c32 F test/corrupt4.test acdb01afaedf529004b70e55de1a6f5a05ae7fff @@ -740,7 +740,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746 -P dfb146ef003bae8ff216baf68cc43d7eb7855c68 -R 7c7f4c4080ad2dff72d55dd2065d8da8 +P 39ce2097da03176e256a2ff35bb857e578f3ca2d +R 0dc08162ecc49e81bc056e17b96d72d2 U danielk1977 -Z 6fc9b62a7a8b05ddc28addf8e5619108 +Z b2bdf8d1bff20b39f70f8c184167a4bf diff --git a/manifest.uuid b/manifest.uuid index 3918a637be..4dc2ef6e69 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -39ce2097da03176e256a2ff35bb857e578f3ca2d \ No newline at end of file +3151dab9c78106217ec80ebadc666dfd11b42029 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 7882c33ae9..07d4bcfd83 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.683 2009/07/13 07:30:53 danielk1977 Exp $ +** $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. @@ -3974,7 +3974,25 @@ static void moveToParent(BtCursor *pCur){ } /* -** Move the cursor to the root page +** 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; @@ -3988,6 +4006,7 @@ static int moveToRoot(BtCursor *pCur){ 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); @@ -4018,8 +4037,16 @@ static int moveToRoot(BtCursor *pCur){ } } + /* 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; @@ -4028,9 +4055,7 @@ static int moveToRoot(BtCursor *pCur){ if( pRoot->nCell==0 && !pRoot->leaf ){ Pgno subpage; if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT; - assert( pRoot->pgno==1 ); subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]); - assert( subpage>0 ); pCur->eState = CURSOR_VALID; rc = moveToChild(pCur, subpage); }else{ @@ -6418,6 +6443,7 @@ int sqlite3BtreeInsert( 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")); diff --git a/test/corrupt.test b/test/corrupt.test index 00dcc0b007..8911393975 100644 --- a/test/corrupt.test +++ b/test/corrupt.test @@ -13,7 +13,7 @@ # 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.11 2009/07/11 17:39:42 danielk1977 Exp $ +# $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} @@ -206,4 +206,24 @@ do_test corrupt-4.2 { 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