]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a segfault that could occur while attempting to add new pages
authordrh <drh@noemail.net>
Fri, 7 Sep 2007 14:32:06 +0000 (14:32 +0000)
committerdrh <drh@noemail.net>
Fri, 7 Sep 2007 14:32:06 +0000 (14:32 +0000)
to the freelist in a corrupt database. (CVS 4414)

FossilOrigin-Name: c8e85fff7ede68f0b8c8ebfe3df4b26a630abeff

manifest
manifest.uuid
src/btree.c
test/corrupt4.test [new file with mode: 0644]

index 6ce8a04624a2310fd66263134ee47d2b547d46bc..043cbc4b1548603a0cafaab4236d7b4773b16e01 100644 (file)
--- 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
index 8c7ff67121888cb19755c925aebb1f752358ea4b..569710b85c07db16fffbdbf1bdac4c8420e70579 100644 (file)
@@ -1 +1 @@
-753908e8411024abd5c3da1b8c62f70e35f8734d
\ No newline at end of file
+c8e85fff7ede68f0b8c8ebfe3df4b26a630abeff
\ No newline at end of file
index c33589ee60e455d1ae9886ad996f66b4cab62e1d..488503ff5a82b8098566f0cdee44f36f494fa33a 100644 (file)
@@ -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 (file)
index 0000000..952df70
--- /dev/null
@@ -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