]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improve coverage of pager.c. (CVS 6158)
authordanielk1977 <danielk1977@noemail.net>
Sat, 10 Jan 2009 16:15:09 +0000 (16:15 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Sat, 10 Jan 2009 16:15:09 +0000 (16:15 +0000)
FossilOrigin-Name: 855c4093cf331496d9ef508011ad814e91e3882f

manifest
manifest.uuid
src/pager.c
src/sqliteLimit.h
test/crash8.test
test/jrnlmode.test
test/malloc.test

index 34f07a27d86b4e7bbe6e8fc8f4f915c41702f3be..4df50766022b079d9f0421002fae737d63808467 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-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
@@ -142,7 +142,7 @@ F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
 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
@@ -159,7 +159,7 @@ F src/shell.c 65d19f8996a160f288087e31810f24025439c62a
 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
@@ -288,7 +288,7 @@ F test/crash4.test 02ff4f15c149ca1e88a5c299b4896c84d9450c3b
 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
@@ -413,7 +413,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
 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
@@ -430,7 +430,7 @@ F test/lock6.test f4e9052b14da3bd6807a757d5aed15c17321031a
 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
@@ -696,7 +696,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 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
index 0f5f9aaded26e8db8c2036efa01fb5b49eca8ddd..abf1c9538f83e9bc6319bfbbb65321d1437a4011 100644 (file)
@@ -1 +1 @@
-3da5578726cb22118dfca38a2098a1e378644387
\ No newline at end of file
+855c4093cf331496d9ef508011ad814e91e3882f
\ No newline at end of file
index db8d0d4e39b86025cc3edb530666df716b9a8add..baae60ec225e40b01a9869130ed789e0b5b416e4 100644 (file)
@@ -18,7 +18,7 @@
 ** 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"
@@ -116,6 +116,14 @@ int sqlite3PagerTrace=1;  /* True to enable tracing */
 # 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
@@ -401,7 +409,7 @@ static int jrnlBufferSize(Pager *pPager){
 
   if( fd->pMethods ){
     dc = sqlite3OsDeviceCharacteristics(fd);
-    nSector = sqlite3OsSectorSize(fd);
+    nSector = pPager->sectorSize;
     szPage = pPager->pageSize;
   }
 
@@ -760,7 +768,8 @@ static int readJournalHdr(
   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 ){
@@ -785,28 +794,41 @@ static int readJournalHdr(
   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);
@@ -1503,7 +1525,7 @@ static int pager_truncate(Pager *pPager, Pgno nPage){
 ** 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);
@@ -1517,6 +1539,9 @@ static void setSectorSize(Pager *pPager){
   if( pPager->sectorSize<512 ){
     pPager->sectorSize = 512;
   }
+  if( pPager->sectorSize>MAX_SECTOR_SIZE ){
+    pPager->sectorSize = MAX_SECTOR_SIZE;
+  }
 }
 
 /*
@@ -2022,9 +2047,9 @@ int sqlite3PagerOpen(
       **    + 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
         {
index 8d77d0da22dc3549d3832903864ae47809c97ebc..26375197bcb13fd4c149614353962ccd8eadadda 100644 (file)
@@ -12,7 +12,7 @@
 ** 
 ** 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
index 3f6c2f35fd03ff52004db6c237e30667137a6366..10a1b2cef542ce66d44c16a71a6fb9671f88edc7 100644 (file)
@@ -15,7 +15,7 @@
 # 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]
@@ -118,13 +118,27 @@ proc read_file {zFile} {
   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]
@@ -148,34 +162,61 @@ do_test crash8-3.4 {
   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
index 7b230e03fcbf4d053f2d13260d34ad61966062b1..540928de1b0894a21a63148006c510091d354b1a 100644 (file)
@@ -11,7 +11,7 @@
 # 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
@@ -419,6 +419,23 @@ ifcapable pragma {
     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 {
index 236dd4f4968d1bfadd2039ee92846e2fe62d2abb..ddd6c2eaf3b46107c57e9f7ff54dddfda0aace72 100644 (file)
@@ -16,7 +16,7 @@
 # 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
@@ -678,7 +678,7 @@ do_malloc_test 29 -sqlprep {
   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));
@@ -708,6 +708,18 @@ do_malloc_test 29 -tclprep {
   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 {