]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Handle corrupt journal file headers correctly. (CVS 1674)
authordanielk1977 <danielk1977@noemail.net>
Wed, 23 Jun 2004 01:05:26 +0000 (01:05 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Wed, 23 Jun 2004 01:05:26 +0000 (01:05 +0000)
FossilOrigin-Name: 46107da7eddbdda8b582e2ece2dc41222a70330a

main.mk
manifest
manifest.uuid
src/pager.c
test/crash.test
test/func.test

diff --git a/main.mk b/main.mk
index 60df83514d3e94a6707a8156e359ca9bbe3cc7f2..06d4eff8159c4f40743852820c2c7ac509917d2c 100644 (file)
--- a/main.mk
+++ b/main.mk
@@ -118,7 +118,6 @@ TESTSRC = \
   $(TOP)/src/os_mac.c \
   $(TOP)/src/os_unix.c \
   $(TOP)/src/os_win.c \
-  $(TOP)/src/os_test.c \
   $(TOP)/src/pager.c \
   $(TOP)/src/pragma.c \
   $(TOP)/src/printf.c \
@@ -274,9 +273,6 @@ opcodes.h:  $(TOP)/src/vdbe.h
 os_mac.o:      $(TOP)/src/os_mac.c $(HDR)
        $(TCCX) -c $(TOP)/src/os_mac.c
 
-os_test.o:     $(TOP)/src/os_test.c $(HDR)
-       $(TCCX) -c $(TOP)/src/os_test.c
-
 os_unix.o:     $(TOP)/src/os_unix.c $(HDR)
        $(TCCX) -c $(TOP)/src/os_unix.c
 
@@ -359,9 +355,9 @@ testfixture$(EXE):  $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC)
                $(TESTSRC) $(TOP)/src/tclsqlite.c \
                libsqlite3.a $(LIBTCL) $(THREADLIB)
 
-testfixturex:  $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC)
-       $(TCCX) $(TCL_FLAGS) -DOS_TEST=1 -DTCLSH=1 -DSQLITE_TEST=1 -o testfixturex \
-               $(TESTSRC) $(TOP)/src/tclsqlite.c \
+crashtest:     $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) $(TOP)/src/os_test.c
+       $(TCCX) $(TCL_FLAGS) -DOS_TEST=1 -DTCLSH=1 -DSQLITE_TEST=1 -o crashtest \
+               $(TESTSRC) $(TOP)/src/os_test.c $(TOP)/src/tclsqlite.c \
                libsqlite3.a $(LIBTCL) $(THREADLIB)
 
 fulltest:      testfixture$(EXE) sqlite3$(EXE)
index 52e8c13c5a8f36d70c64dd312d4f6645eb82369a..2f812b242964d81703faaa041c3cac0fa2466f8e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sa\scomment\sto\sthe\soutput\sbuffer\sallocation\sin\ssqlite3VdbeMemTranslate()\s(CVS\s1673)
-D 2004-06-23T00:23:49
+C Handle\scorrupt\sjournal\sfile\sheaders\scorrectly.\s(CVS\s1674)
+D 2004-06-23T01:05:27
 F Makefile.in 0a3d7aaefa50717bd550b0cf568a51072c4c103c
 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -17,7 +17,7 @@ F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
 F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
 F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
-F main.mk 5dbdfd52ee306c553c88278d7dc4adb58a662209
+F main.mk a14f6389bce136c336206ec58b69305ab12ba5fa
 F mkdll.sh 68d34a961a1fdfa15ef27fc4f4740be583112124
 F publish.sh 4193d9022fb7cf9beecd313bed3d1d68b8386fbe
 F spec.template a38492f1c1dd349fc24cb0565e08afc53045304b
@@ -50,7 +50,7 @@ F src/os_unix.c 39e73ed02fc992a6bfc52200ea26704633412cc0
 F src/os_unix.h 00c1f82b526ab2fb7ee5ddd555ea4ed68363c93a
 F src/os_win.c 84549f6cc815237533c5d0eb3697352b03478d96
 F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44
-F src/pager.c 5fac95a8fef916a4c5915ccc3b8dc72312681880
+F src/pager.c 42297421e9e7646f99b332c69f3f8085c1d765bf
 F src/pager.h bc58d32a9dee464f7268fb68652c130a4216e438
 F src/parse.y 097438674976355a10cf177bd97326c548820b86
 F src/pragma.c 0750e1c360647dbe0a991f16133b0fe5e42e5039
@@ -104,7 +104,7 @@ F test/collate4.test 0e9fc08ffcf6eddf72e354a15de06688fa86db31
 F test/collate5.test 1dd5f0f508c46667f9d4606c7950c414b0bdc0d5
 F test/collate6.test 2a45768914f04c1447a69d1358bbede376552675
 F test/conflict.test c5b849b01cfbe0a4f63a90cba6f68e2fe3a75f87
-F test/crash.test b6ff4701ca4c30553dc819eab9d8b1226ca39af2
+F test/crash.test fa7c6ef4d1ac1aa2d14d8afd1583cef8f8e2a0e4
 F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
 F test/date.test aed5030482ebc02bd8d386c6c86a29f694ab068d
 F test/delete.test 4f0c86e2bebdc822d179c80697b1ceabe6bbcd07
@@ -113,7 +113,7 @@ F test/enc2.test 57c847492afd46eef7a498fc3853fe909a40fef7
 F test/enc3.test 315f302ed9a6042be76710eb6aa70e4551e9aa73
 F test/expr.test b4e945265c4c697bf5213b72558914ba10a989cc
 F test/fkey1.test d65c824459916249bee501532d6154ddab0b5db7
-F test/func.test c97954ad23bdbc58e2b73f264f6a006bae79f626
+F test/func.test 95eba35f06e56e66fa40726957ce103b4e6ffe73
 F test/hook.test c4102c672d67f8fb60ea459842805abcba69a747
 F test/in.test b92a2df9162e1cbd33c6449a29a05e6955b1741a
 F test/index.test b6941dd532815f278042b85f79b1a6dc16c4d729
@@ -229,7 +229,7 @@ F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
 F www/version3.tcl 563ba3ac02f64da27ab17f3edbe8e56bfd0293fb
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P cb4e242e83ba111c5da1f9662fda5a890051e7b0
-R bd4ff00f259823f00b7fc8204e6c5fa3
+P e2f7f182987fbfe8611ead8bd1f12b2e8b47f6dc
+R 8314e42b760c1a8a452b6f1accd15858
 U danielk1977
-Z ed06ef82d5f64ca5dbd5ac31ceda856c
+Z 0fc9a3cf7f51cb64d701f7be6ce96ff8
index e7598a175695d3adde53ffacdb81714109b56782..6307d2cddfe8b3b8a6238830a65d1e8e535697b2 100644 (file)
@@ -1 +1 @@
-e2f7f182987fbfe8611ead8bd1f12b2e8b47f6dc
\ No newline at end of file
+46107da7eddbdda8b582e2ece2dc41222a70330a
\ No newline at end of file
index 4f73e7629bbd417ef5ae48245b2434e87193dcfc..9e46ef899cf535d11da32656fd25ca268ac034c6 100644 (file)
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.135 2004/06/22 12:18:32 danielk1977 Exp $
+** @(#) $Id: pager.c,v 1.136 2004/06/23 01:05:27 danielk1977 Exp $
 */
 #include "os.h"         /* Must be first to enable large file support */
 #include "sqliteInt.h"
@@ -792,10 +792,13 @@ static int pager_reload_cache(Pager *pPager){
 ** deleted when the power is restored) we don't care.  
 **
 ** If the file opened as the journal file is not a well-formed
-** journal file then the database will likely already be
-** corrupted, so the PAGER_ERR_CORRUPT bit is set in pPager->errMask
-** and SQLITE_CORRUPT is returned.  If it all works, then this routine
-** returns SQLITE_OK.
+** journal file then all pages up to the first corrupted page are rolled
+** back (or no pages if the journal header is corrupted). The journal file
+** is then deleted and SQLITE_OK returned, just as if no corruption had
+** been encountered.
+**
+** If an I/O or malloc() error occurs, the journal-file is not deleted
+** and an error code is returned.
 */
 static int pager_playback(Pager *pPager, int useJournalSize){
   off_t szJ;               /* Size of the journal file in bytes */
@@ -831,7 +834,6 @@ static int pager_playback(Pager *pPager, int useJournalSize){
   ** at the beginning of the journal. */
   rc = sqlite3OsRead(&pPager->jfd, aMagic, sizeof(aMagic));
   if( rc!=SQLITE_OK || memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){
-    rc = SQLITE_PROTOCOL;
     goto end_playback;
   }
 
@@ -857,6 +859,7 @@ static int pager_playback(Pager *pPager, int useJournalSize){
   ** specified, only proceed with the playback if it still exists. */
   rc = read32bits(&pPager->jfd, &nMaster);
   if( rc ) goto end_playback;
+  if( szJ < 24+nMaster ) goto end_playback;
   if( nMaster>0 ){
     zMaster = sqliteMalloc(nMaster);
     if( !zMaster ){
@@ -908,15 +911,7 @@ end_playback:
     }
     sqliteFree(zMaster);
   }
-  if( rc!=SQLITE_OK ){
-    /* FIX ME: We shouldn't delete the journal if an error occured during
-    ** rollback. It may have been a transient error and the rollback may
-    ** succeed next time it is attempted.
-    */
-    pager_unwritelock(pPager);
-    pPager->errMask |= PAGER_ERR_CORRUPT;
-    rc = SQLITE_CORRUPT;
-  }else{
+  if( rc==SQLITE_OK ){
     rc = pager_unwritelock(pPager);
   }
   return rc;
index 8e037647216205c797b25716b33e21207707d483..e287c33051f46da4b730c38bbc6df9866b1463c5 100644 (file)
 #***********************************************************************
 # This file implements regression tests for SQLite library.
 #
-# $Id: crash.test,v 1.1 2004/06/22 13:12:52 danielk1977 Exp $
+# $Id: crash.test,v 1.2 2004/06/23 01:05:27 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
 
-proc run_testfixturex {script} {
+# This proc execs a seperate process that crashes midway through executing
+# the SQL script $sql on database test.db.
+#
+# Argument $crashdelay indicates the number of file closes or syncs to wait
+# before crashing. When a crash occurs a random subset of unsynced writes
+# are written into any open files.
+proc crashsql {crashdelay sql} {
+
   set f [open crash.tcl w]
-  puts $f $script
+  puts $f "sqlite3_crashseed $crashdelay"
+  puts $f "sqlite3 db test.db"
+  puts $f "db eval {"
+  puts $f   "$sql"
+  puts $f "}"
   close $f
 
-  exec ./testfixturex crash.tcl
+  exec [file join . crashtest] crash.tcl
 }
 
+# Simple crash test:
+#
+# crash-1.1: Create a database with a table with two rows.
+# crash-1.2: Run a 'DELETE FROM abc WHERE a = 1' that crashes during
+#            journal-sync
+# crash-1.3: Ensure the database is in the same state as after crash-1.1.
+# crash-1.4: Run a 'DELETE FROM abc WHERE a = 1' that crashes during
+#            database-sync
+# crash-1.5: Ensure the database is in the same state as after crash-1.1.
+#
 do_test crash-1.1 {
   execsql {
     CREATE TABLE abc(a, b, c);
@@ -30,43 +51,32 @@ do_test crash-1.1 {
     INSERT INTO abc VALUES(4, 5, 6);
   }
 } {}
-
 do_test crash-1.2 {
-  set script {
-    sqlite3_crashseed 1
-    sqlite3 db test.db 
-    db eval {pragma synchronous=full;}
-    db eval {DELETE FROM abc WHERE a = 1;}
-  }
   catch {
-    run_testfixturex $script
+    crashsql 1 {
+      DELETE FROM abc WHERE a = 1;
+    }
   } msg
   set msg
 } {child process exited abnormally}
-
 do_test crash-1.3 {
   catchsql {
     SELECT * FROM abc;
   }
 } {0 {1 2 3 4 5 6}}
-
 do_test crash-1.4 {
-  set script {
-    sqlite3_crashseed 2
-    sqlite3 db test.db 
-    db eval {DELETE FROM abc WHERE a = 1;}
-  }
   catch {
-    run_testfixturex $script
+   crashsql 1 {
+      DELETE FROM abc WHERE a = 1;
+    }
   } msg
   set msg
 } {child process exited abnormally}
-
 do_test crash-1.5 {
-  catch {
+  catchsql {
     SELECT * FROM abc;
   }
-} {1 2 3 4 5 6}
+} {0 {1 2 3 4 5 6}}
 
 finish_test
 
index de8ab615ff01e22e8ecb2165468674bf8eae4dbd..590aaa8cc41c3a1fe67538c9160685672652265e 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing built-in functions.
 #
-# $Id: func.test,v 1.24 2004/06/19 17:33:08 drh Exp $
+# $Id: func.test,v 1.25 2004/06/23 01:05:27 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -392,6 +392,7 @@ do_test func-13.1 {
     SELECT test_auxdata('hello world');
   }
 } {0}
+
 do_test func-13.2 {
   execsql {
     CREATE TABLE t4(a, b);
@@ -434,5 +435,4 @@ do_test func-13.7 {
   lappend res [sqlite3_finalize $STMT]
 } {{0 0} {1 0} SQLITE_OK}
 
-
 finish_test