diff --git a/manifest b/manifest index 6ce8a04624..043cbc4b15 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sbeginning\sof\sthe\sthread-safety\stests.\sThere\sare\smore\sto\scome.\s(CVS\s4413) -D 2007-09-07T11:29:25 +C Fix\sa\ssegfault\sthat\scould\soccur\swhile\sattempting\sto\sadd\snew\spages\nto\sthe\sfreelist\sin\sa\scorrupt\sdatabase.\s(CVS\s4414) +D 2007-09-07T14:32:07 F Makefile.in cbfb898945536a8f9ea8b897e1586dd1fdbcc5db F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -81,7 +81,7 @@ F src/analyze.c 49b4bd45eb286d833793ed6bf72355a5c1974865 F src/attach.c 02fd8779270b1df1c63e7ba6e6655b960fa0f3d5 F src/auth.c d41c34f3150b3b8248d364770ef922bbcefbff82 F src/btmutex.c 442be6f068d77ca9ffd69899cf0a3943c244548c -F src/btree.c 9d684690afbc66f20905c408e2e018008cf99277 +F src/btree.c 30f7efafc4f5818477b80cf77b3d05acd2805ab7 F src/btree.h d0736ebca4b6eafbdd823c46a8de574cea078211 F src/btreeInt.h 4330c19b8314545fdb209cc77e2a57f6a5290e9c F src/build.c 94d0d6dfd1e706c480903fbdda2e77466f21b898 @@ -232,6 +232,7 @@ F test/conflict.test 79b5214ef7a52f3e58a50ae5c60c37e7594d04e9 F test/corrupt.test 18c7a995b1af76a8c8600b996257f2c7b7bff083 F test/corrupt2.test 572f8df0303d0ce63ddad5c5c9101a83a345ae46 F test/corrupt3.test 263e8bb04e2728df832fddf6973cf54c91db0c32 +F test/corrupt4.test acdb01afaedf529004b70e55de1a6f5a05ae7fff F test/crash.test 24020168cc42977a4dd83ff78d2b5eb6577715db F test/crash2.test 26d7a4c5520201e5de2c696ea51ab946b59dc0e9 F test/crash3.test 0b09687ae1a3ccbcefdfaeb4b963e26e36255d76 @@ -572,7 +573,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P f780a17f4b0e679479c2b368d8659a0ee61c343d -R e4d6e8dadc7d65c050f265cc5a051321 -U danielk1977 -Z 57428b4bd8d43ba4be46844bba20292d +P 753908e8411024abd5c3da1b8c62f70e35f8734d +R 694839393b8154b22df691b07855d693 +U drh +Z 118daf76b8bcf6c5ec13879a5aaee9dc diff --git a/manifest.uuid b/manifest.uuid index 8c7ff67121..569710b85c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -753908e8411024abd5c3da1b8c62f70e35f8734d \ No newline at end of file +c8e85fff7ede68f0b8c8ebfe3df4b26a630abeff \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index c33589ee60..488503ff5a 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.424 2007/09/06 23:39:37 drh Exp $ +** $Id: btree.c,v 1.425 2007/09/07 14:32:07 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -4140,12 +4140,15 @@ static int freePage(MemPage *pPage){ /* The trunk is full. Turn the page being freed into a new ** trunk page with no leaves. */ rc = sqlite3PagerWrite(pPage->pDbPage); - if( rc ) return rc; - put4byte(pPage->aData, pTrunk->pgno); - put4byte(&pPage->aData[4], 0); - put4byte(&pPage1->aData[32], pPage->pgno); - TRACE(("FREE-PAGE: %d new trunk page replacing %d\n", - pPage->pgno, pTrunk->pgno)); + if( rc==SQLITE_OK ){ + put4byte(pPage->aData, pTrunk->pgno); + put4byte(&pPage->aData[4], 0); + put4byte(&pPage1->aData[32], pPage->pgno); + TRACE(("FREE-PAGE: %d new trunk page replacing %d\n", + pPage->pgno, pTrunk->pgno)); + } + }else if( k<0 ){ + rc = SQLITE_CORRUPT; }else{ /* Add the newly freed page as a leaf on the current trunk */ rc = sqlite3PagerWrite(pTrunk->pDbPage); diff --git a/test/corrupt4.test b/test/corrupt4.test new file mode 100644 index 0000000000..952df70fdb --- /dev/null +++ b/test/corrupt4.test @@ -0,0 +1,74 @@ +# 2007 Sept 7 +# +# 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. +# +#*********************************************************************** +# 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: corrupt4.test,v 1.1 2007/09/07 14:32:07 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# We must have the page_size pragma for these tests to work. +# +ifcapable !pager_pragmas { + finish_test + return +} + +# Create a database with a freelist containing at least two pages. +# +do_test corrupt4-1.1 { + set bigstring [string repeat 0123456789 200] + execsql { + PRAGMA auto_vacuum=OFF; + PRAGMA page_size=1024; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES($bigstring); + CREATE TABLE t2(y); + INSERT INTO t2 VALUES(1); + DROP TABLE t1; + } + file size test.db +} [expr {1024*4}] + +# Verify that there are two pages on the freelist. +# +do_test corrupt4-1.2 { + execsql {PRAGMA freelist_count} +} {2} + +# Get the page number for the trunk of the freelist. +# +set trunkpgno [hexio_get_int [hexio_read test.db 32 4]] +set baseaddr [expr {($trunkpgno-1)*1024}] + +# Verify that the trunk of the freelist has exactly one +# leaf. +# +do_test corrupt4-1.3 { + hexio_get_int [hexio_read test.db [expr {$::baseaddr+4}] 4] +} {1} + +# Insert a negative number as the number of leaves on the trunk. +# Then try to add a new element to the freelist. +# +do_test corrupt4-1.4 { + hexio_write test.db [expr {$::baseaddr+4}] [hexio_render_int32 -100000000] + db close + sqlite3 db test.db + catchsql { + DROP TABLE t2 + } +} {1 {database disk image is malformed}} + +finish_test