Handle corrupt journal file headers correctly. (CVS 1674)

FossilOrigin-Name: 46107da7eddbdda8b582e2ece2dc41222a70330a
This commit is contained in:
danielk1977 2004-06-23 01:05:26 +00:00
parent d7e69648c1
commit ece80f1e48
6 changed files with 58 additions and 57 deletions

10
main.mk
View File

@ -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)

View File

@ -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

View File

@ -1 +1 @@
e2f7f182987fbfe8611ead8bd1f12b2e8b47f6dc
46107da7eddbdda8b582e2ece2dc41222a70330a

View 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;

View File

@ -10,19 +10,40 @@
#***********************************************************************
# 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

View 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