-C Fix\sa\sbug\scaused\sby\soverzealous\scode\stest\scoverage\ssimplifications.\nBug\sfound\sby\sTH3.\s(CVS\s6157)
-D 2009-01-10T15:34:12
+C Improve\scoverage\sof\spager.c.\s(CVS\s6158)
+D 2009-01-10T16:15:09
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 05461a9b5803d5ad10c79f989801e9fd2cc3e592
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5
F src/os_unix.c 7825c6178597713382d74adbf8c8c00ffcdc42d4
F src/os_win.c 496e3ceb499aedc63622a89ef76f7af2dd902709
-F src/pager.c 97bfbacae6131b8d228628803606e98dd763b474
+F src/pager.c a1e23f2c55bda1303cb6236d4aca9666e58eb610
F src/pager.h 9870acb2d653848d90d765d7cbf163496d6c8111
F src/parse.y 4d0e33a702dc3ea7b69d8ae1914b3fbd32e46057
F src/pcache.c 16dc8da6e6ba6250f8dfd9ee46036db1cbceedc6
F src/sqlite.h.in 6cd2489e40fe97ba58c60044a4ced377e08b6d09
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
F src/sqliteInt.h 4b2a8eb466c30daa90d25f9d3bb2e85b60ad47af
-F src/sqliteLimit.h 651a2757ba55aeba1da167786b6a8c3404433940
+F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
F src/table.c 23db1e5f27c03160987c122a078b4bb51ef0b2f8
F src/tclsqlite.c 4415e1033bd3e92b05a6a9cde911ee4de3b82df9
F test/crash5.test 80a2f7073381837fc082435c97df52a830abcd80
F test/crash6.test 9c730cf06335003cb1f5cfceddacd044155336e0
F test/crash7.test e20a7b9ee1d16eaef7c94a4cb7ed2191b4d05970
-F test/crash8.test 2ee8ecfed37eea4b987148fe36d6b56175c7d049
+F test/crash8.test 5b0e499c1dfaa2025e8ab69e4be32f71d4d92b23
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F test/createtab.test 199cf68f44e5d9e87a0b8afc7130fdeb4def3272
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe
F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19
-F test/jrnlmode.test e004a5ed138e06464d74dbd6bead01908f264c52
+F test/jrnlmode.test a77f95a7cbdc8373582fd274f24124ad0d3a8fb6
F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F test/like.test 22f7857f9d7da7ff5061ded8806c43a6271109fc
F test/lookaside.test e69f822f13745f1d5c445c6e30e30f059f30c8e5
F test/main.test 187a9a1b5248ed74a83838c581c15ec6023b555b
F test/make-where7.tcl 40bb740b37eead343eaf57b74ab72d2a5a304745
-F test/malloc.test 86f378c52202b5b39b54a7fc560a4a75d77ce4f1
+F test/malloc.test 95e94f8a3dd1169c8774788ec4148ea032ea20d8
F test/malloc3.test 4bc57f850b212f706f3e1b37c4eced1d5a727cd1
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
F test/malloc5.test 20d1a0884b03edf811bfd7005faade028367e7c8
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 2cbea64fb00a1b5b8aa0e9c958b2a09256ae59bc
-R 7759d6bbe5785c316ce1fcb98ad155c6
-U drh
-Z 8f01cd8c083356c8b7a4a4354e84f698
+P 3da5578726cb22118dfca38a2098a1e378644387
+R 320ab8e7bd88e5e4d3a0d64f8789cffb
+U danielk1977
+Z 43f0761b39243fe434b2dca241a4ad9a
-3da5578726cb22118dfca38a2098a1e378644387
\ No newline at end of file
+855c4093cf331496d9ef508011ad814e91e3882f
\ No newline at end of file
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.544 2009/01/09 17:11:05 danielk1977 Exp $
+** @(#) $Id: pager.c,v 1.545 2009/01/10 16:15:09 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
# define CODEC2(P,D,N,X) ((char*)D)
#endif
+/*
+** The maximum allowed sector size. 16MB. If the xSectorsize() method
+** returns a value larger than this, then MAX_SECTOR_SIZE is used instead.
+** This could conceivably cause corruption following a power failure on
+** such a system. This is currently an undocumented limit.
+*/
+#define MAX_SECTOR_SIZE 0x0100000
+
/*
** An instance of the following structure is allocated for each active
** savepoint and statement transaction in the system. All such structures
if( fd->pMethods ){
dc = sqlite3OsDeviceCharacteristics(fd);
- nSector = sqlite3OsSectorSize(fd);
+ nSector = pPager->sectorSize;
szPage = pPager->pageSize;
}
int rc;
unsigned char aMagic[8]; /* A buffer to hold the magic header */
i64 jrnlOff;
- int iPageSize;
+ u32 iPageSize;
+ u32 iSectorSize;
seekJournalHdr(pPager);
if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
rc = read32bits(pPager->jfd, jrnlOff+8, pDbSize);
if( rc ) return rc;
- rc = read32bits(pPager->jfd, jrnlOff+16, (u32 *)&iPageSize);
- if( rc==SQLITE_OK
- && iPageSize>=512
- && iPageSize<=SQLITE_MAX_PAGE_SIZE
- && ((iPageSize-1)&iPageSize)==0
- ){
- u16 pagesize = (u16)iPageSize;
- rc = sqlite3PagerSetPagesize(pPager, &pagesize);
- }
- if( rc ) return rc;
+ if( pPager->journalOff==0 ){
+ rc = read32bits(pPager->jfd, jrnlOff+16, &iPageSize);
+ if( rc ) return rc;
- /* Update the assumed sector-size to match the value used by
- ** the process that created this journal. If this journal was
- ** created by a process other than this one, then this routine
- ** is being called from within pager_playback(). The local value
- ** of Pager.sectorSize is restored at the end of that routine.
- */
- rc = read32bits(pPager->jfd, jrnlOff+12, &pPager->sectorSize);
- if( rc ) return rc;
- if( (pPager->sectorSize & (pPager->sectorSize-1))!=0
- || pPager->sectorSize>0x1000000 ){
- return SQLITE_DONE;
+ if( iPageSize<512
+ || iPageSize>SQLITE_MAX_PAGE_SIZE
+ || ((iPageSize-1)&iPageSize)!=0
+ ){
+ /* If the page-size in the journal-header is invalid, then the process
+ ** that wrote the journal-header must have crashed before the header
+ ** was synced. In this case stop reading the journal file here.
+ */
+ rc = SQLITE_DONE;
+ }else{
+ u16 pagesize = (u16)iPageSize;
+ rc = sqlite3PagerSetPagesize(pPager, &pagesize);
+ assert( rc!=SQLITE_OK || pagesize==(u16)iPageSize );
+ }
+ if( rc ) return rc;
+
+ /* Update the assumed sector-size to match the value used by
+ ** the process that created this journal. If this journal was
+ ** created by a process other than this one, then this routine
+ ** is being called from within pager_playback(). The local value
+ ** of Pager.sectorSize is restored at the end of that routine.
+ */
+ rc = read32bits(pPager->jfd, jrnlOff+12, &iSectorSize);
+ if( rc ) return rc;
+ if( (iSectorSize&(iSectorSize-1))
+ || iSectorSize<512
+ || iSectorSize>MAX_SECTOR_SIZE
+ ){
+ return SQLITE_DONE;
+ }
+ pPager->sectorSize = iSectorSize;
}
pPager->journalOff += JOURNAL_HDR_SZ(pPager);
** Set the sectorSize for the given pager.
**
** The sector size is at least as big as the sector size reported
-** by sqlite3OsSectorSize(). The minimum sector size is 512.
+** by sqlite3OsSectorSize(). The minimum sector size is 512.
*/
static void setSectorSize(Pager *pPager){
assert(pPager->fd->pMethods||pPager->tempFile);
if( pPager->sectorSize<512 ){
pPager->sectorSize = 512;
}
+ if( pPager->sectorSize>MAX_SECTOR_SIZE ){
+ pPager->sectorSize = MAX_SECTOR_SIZE;
+ }
}
/*
** + The largest page size that can be written atomically.
*/
if( rc==SQLITE_OK && !readOnly ){
- int iSectorSize = sqlite3OsSectorSize(pPager->fd);
- if( szPageDflt<iSectorSize ){
- szPageDflt = iSectorSize;
+ setSectorSize(pPager);
+ if( szPageDflt<pPager->sectorSize ){
+ szPageDflt = pPager->sectorSize;
}
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
{
**
** This file defines various limits of what SQLite can process.
**
-** @(#) $Id: sqliteLimit.h,v 1.9 2009/01/07 16:15:43 danielk1977 Exp $
+** @(#) $Id: sqliteLimit.h,v 1.10 2009/01/10 16:15:09 danielk1977 Exp $
*/
/*
/* Maximum page size. The upper bound on this value is 32768. This a limit
** imposed by the necessity of storing the value in a 2-byte unsigned integer
** and the fact that the page size must be a power of 2.
+**
+** If this limit is changed, then the compiled library is technically
+** incompatible with an SQLite library compiled with a different limit. If
+** a process operating on a database with a page-size of 65536 bytes
+** crashes, then an instance of SQLite compiled with the default page-size
+** limit will not be able to rollback the aborted transaction. This could
+** lead to database corruption.
*/
#ifndef SQLITE_MAX_PAGE_SIZE
# define SQLITE_MAX_PAGE_SIZE 32768
# Later: Also, some other specific scenarios required for coverage
# testing that do not lead to corruption.
#
-# $Id: crash8.test,v 1.2 2009/01/09 10:49:14 danielk1977 Exp $
+# $Id: crash8.test,v 1.3 2009/01/10 16:15:09 danielk1977 Exp $
set testdir [file dirname $argv0]
close $fd
return $zData
}
+proc write_file {zFile zData} {
+ set fd [open $zFile w]
+ fconfigure $fd -translation binary
+ puts -nonewline $fd $zData
+ close $fd
+}
# The following tests check that SQLite will not roll back a hot-journal
# file if the sector-size field in the first journal file header is
# suspect. Definition of suspect:
#
+# a) Not a power of 2, or (crash8-3.5)
+# b) Greater than 0x01000000 (16MB), or (crash8-3.6)
+# c) Less than 512. (crash8-3.7)
+#
+# Also test that SQLite will not rollback a hot-journal file with a
+# suspect page-size. In this case "suspect" means:
+#
# a) Not a power of 2, or
-# b) Greater than 0x1000000 (16MB).
+# b) Less than 512, or
+# c) Greater than SQLITE_MAX_PAGE_SIZE
#
do_test crash8-3.1 {
list [file exists test.db-joural] [file exists test.db]
binary scan [string range $zJournal 20 23] I nSector
set nSector
} {512}
+
do_test crash8-3.5 {
- set zJournal2 [
- string replace $zJournal 20 23 [binary format I 511]
- ]
- set fd [open test.db-journal w]
- fconfigure $fd -translation binary
- puts -nonewline $fd $zJournal2
- close $fd
-
+ set zJournal2 [string replace $zJournal 20 23 [binary format I 513]]
+ write_file test.db-journal $zJournal2
+
execsql {
SELECT count(*) FROM t1;
PRAGMA integrity_check
}
} {0 ok}
do_test crash8-3.6 {
- set zJournal2 [
- string replace $zJournal 20 23 [binary format I [expr 0x2000000]]
- ]
- set fd [open test.db-journal w]
- fconfigure $fd -translation binary
- puts -nonewline $fd $zJournal2
- close $fd
+ set zJournal2 [string replace $zJournal 20 23 [binary format I 0x2000000]]
+ write_file test.db-journal $zJournal2
execsql {
SELECT count(*) FROM t1;
PRAGMA integrity_check
}
} {0 ok}
do_test crash8-3.7 {
+ set zJournal2 [string replace $zJournal 20 23 [binary format I 256]]
+ write_file test.db-journal $zJournal2
+ execsql {
+ SELECT count(*) FROM t1;
+ PRAGMA integrity_check
+ }
+} {0 ok}
+
+do_test crash8-3.8 {
+ set zJournal2 [string replace $zJournal 24 27 [binary format I 513]]
+ write_file test.db-journal $zJournal2
+
+ execsql {
+ SELECT count(*) FROM t1;
+ PRAGMA integrity_check
+ }
+} {0 ok}
+do_test crash8-3.9 {
+ set big [expr $SQLITE_MAX_PAGE_SIZE * 2]
+ set zJournal2 [string replace $zJournal 24 27 [binary format I $big]]
+ write_file test.db-journal $zJournal2
+ execsql {
+ SELECT count(*) FROM t1;
+ PRAGMA integrity_check
+ }
+} {0 ok}
+do_test crash8-3.10 {
+ set zJournal2 [string replace $zJournal 24 27 [binary format I 256]]
+ write_file test.db-journal $zJournal2
+ execsql {
+ SELECT count(*) FROM t1;
+ PRAGMA integrity_check
+ }
+} {0 ok}
+
+do_test crash8-3.11 {
set fd [open test.db-journal w]
fconfigure $fd -translation binary
puts -nonewline $fd $zJournal
# This file implements regression tests for SQLite library. The focus
# of these tests is the journal mode pragma.
#
-# $Id: jrnlmode.test,v 1.10 2009/01/09 10:49:14 danielk1977 Exp $
+# $Id: jrnlmode.test,v 1.11 2009/01/10 16:15:09 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set sz [file size test.db-journal]
expr {$sz>=$journalsize}
} {1}
+
+ # Test a size-limit of 0.
+ #
+ do_test jrnlmode-5.20 {
+ execsql {
+ PRAGMA journal_size_limit = 0;
+ BEGIN;
+ UPDATE t1 SET a = randomblob(1000);
+ }
+ } {0}
+ do_test jrnlmode-5.21 {
+ expr {[file size test.db-journal] > 1024}
+ } {1}
+ do_test jrnlmode-5.22 {
+ execsql COMMIT
+ list [file exists test.db-journal] [file size test.db-journal]
+ } {1 0}
}
ifcapable pragma {
# to see what happens in the library if a malloc were to really fail
# due to an out-of-memory situation.
#
-# $Id: malloc.test,v 1.72 2009/01/10 11:13:40 danielk1977 Exp $
+# $Id: malloc.test,v 1.73 2009/01/10 16:15:09 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
INSERT INTO t1 SELECT * FROM t1 UNION ALL SELECT * FROM t1;
}
-do_malloc_test 29 -tclprep {
+do_malloc_test 30 -tclprep {
db eval {
CREATE TABLE t1(x PRIMARY KEY);
INSERT INTO t1 VALUES(randstr(500,500));
SELECT * FROM t1 ORDER BY x;
}
+# After committing a transaction in persistent-journal mode, if a journal
+# size limit is configured SQLite may attempt to truncate the journal file.
+# This test verifies the libraries response to a malloc() failure during
+# this operation.
+#
+do_malloc_test 31 -sqlprep {
+ PRAGMA journal_mode = persist;
+ PRAGMA journal_size_limit = 1024;
+ CREATE TABLE t1(a PRIMARY KEY, b);
+} -sqlbody {
+ INSERT INTO t1 VALUES(1, 2);
+}
# Ensure that no file descriptors were leaked.
do_test malloc-99.X {