-C Remove\san\sunused\s#define\sand\sadd\san\sassert(),\sboth\sassociated\swith\sWITH\slogic.
-D 2014-01-20T14:58:55.056
+C Handle\sa\sfew\sobscure\sproblems\sthat\scould\smanifest\sif\sa\sdatabase\scorrupted\sin\sa\scertain\sway\swas\swritten\sby\sa\sconnection\sin\sthe\smiddle\sof\sa\sSELECT\sstatement\son\sthe\ssame\sdb.
+D 2014-01-20T18:25:44.841
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
-F src/btree.c c15e1722696b66c4029c487acfb830b0985bf142
+F src/btree.c 02e1a4e71d8fc37e9fd5216c15d989d148a77c87
F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9
F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0
F src/build.c 7e6c275ab1731510d6f793d0f88373ab3e858e69
F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
F test/corruptG.test c150f156dace653c00a121ad0f5772a0568c41ba
+F test/corruptH.test 0a247f3dc8a8f3578db5f639d86c6bb4d520207f
F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 8a973912e98c9b1bb9d3f914527d35c1e7f2011a
-R bcd03400ea7bd2e959020317f5125b8b
-U drh
-Z f5ee43186682e26d4e29624d49787797
+P a06235e0f6aa1e8fefa3f2873ee035eac9dac750
+R 05b4cba80caa92c648883df94b9ec5d5
+U dan
+Z 37a297a819c7d62ae4b0e647e3e25c85
-a06235e0f6aa1e8fefa3f2873ee035eac9dac750
\ No newline at end of file
+eba8a564e62f84a9620008beead80081fe90a1b7
\ No newline at end of file
int iPage = pCur->iPage;
memset(&info, 0, sizeof(info));
btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info);
- assert( memcmp(&info, &pCur->info, sizeof(info))==0 );
+ assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 );
}
#else
#define assertCellInfo(x)
return rc;
}
pCur->iPage = 0;
-
- /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
- ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
- ** NULL, the caller expects a table b-tree. If this is not the case,
- ** return an SQLITE_CORRUPT error. */
- assert( pCur->apPage[0]->intKey==1 || pCur->apPage[0]->intKey==0 );
- if( (pCur->pKeyInfo==0)!=pCur->apPage[0]->intKey ){
- return SQLITE_CORRUPT_BKPT;
- }
}
-
- /* Assert that the root page is of the correct type. This must be the
- ** case as the call to this function that loaded the root-page (either
- ** this call or a previous invocation) would have detected corruption
- ** if the assumption were not true, and it is not possible for the flags
- ** byte to have been modified while this cursor is holding a reference
- ** to the page. */
pRoot = pCur->apPage[0];
assert( pRoot->pgno==pCur->pgnoRoot );
- assert( pRoot->isInit && (pCur->pKeyInfo==0)==pRoot->intKey );
+
+ /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
+ ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
+ ** NULL, the caller expects a table b-tree. If this is not the case,
+ ** return an SQLITE_CORRUPT error.
+ **
+ ** Earlier versions of SQLite assumed that this test could not fail
+ ** if the root page was already loaded when this function was called (i.e.
+ ** if pCur->iPage>=0). But this is not so if the database is corrupted
+ ** in such a way that page pRoot is linked into a second b-tree table
+ ** (or the freelist). */
+ assert( pRoot->intKey==1 || pRoot->intKey==0 );
+ if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){
+ return SQLITE_CORRUPT_BKPT;
+ }
pCur->aiIdx[0] = 0;
pCur->info.nSize = 0;
if( rc==SQLITE_OK ){
if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){
releasePage(*ppPage);
+ *ppPage = 0;
return SQLITE_CORRUPT_BKPT;
}
(*ppPage)->isInit = 0;
--- /dev/null
+# 2014-01-20
+#
+# 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.
+#
+#***********************************************************************
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix corruptH
+
+# Do not use a codec for tests in this file, as the database file is
+# manipulated directly using tcl scripts (using the [hexio_write] command).
+#
+do_not_use_codec
+database_may_be_corrupt
+
+# Initialize the database.
+#
+do_execsql_test 1.1 {
+ PRAGMA page_size=1024;
+
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
+ INSERT INTO t1 VALUES(1, 'one');
+ INSERT INTO t1 VALUES(2, 'two');
+
+ CREATE TABLE t2(x);
+ INSERT INTO t2 VALUES(randomblob(200));
+ INSERT INTO t2 SELECT randomblob(200) FROM t2;
+ INSERT INTO t2 SELECT randomblob(200) FROM t2;
+ INSERT INTO t2 SELECT randomblob(200) FROM t2;
+ INSERT INTO t2 SELECT randomblob(200) FROM t2;
+ INSERT INTO t2 SELECT randomblob(200) FROM t2;
+ INSERT INTO t2 SELECT randomblob(200) FROM t2;
+} {}
+
+# Corrupt the file so that the root page of t1 is also linked into t2 as
+# a leaf page.
+#
+do_test 1.2 {
+ db eval { SELECT name, rootpage FROM sqlite_master } {
+ set r($name) $rootpage
+ }
+ db close
+ hexio_write test.db [expr {($r(t2)-1)*1024 + 11}] [format %.2X $r(t1)]
+ sqlite3 db test.db
+} {}
+
+do_test 1.3 {
+ db eval { PRAGMA secure_delete=1 }
+ list [catch {
+ db eval { SELECT * FROM t1 WHERE a IN (1, 2) } {
+ db eval { DELETE FROM t2 }
+ }
+ } msg] $msg
+} {1 {database disk image is malformed}}
+
+#-------------------------------------------------------------------------
+reset_db
+
+# Initialize the database.
+#
+do_execsql_test 2.1 {
+ PRAGMA page_size=1024;
+
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
+ INSERT INTO t1 VALUES(1, 'one');
+ INSERT INTO t1 VALUES(2, 'two');
+
+ CREATE TABLE t3(x);
+
+ CREATE TABLE t2(x PRIMARY KEY) WITHOUT ROWID;
+ INSERT INTO t2 VALUES(randomblob(100));
+
+ DROP TABLE t3;
+} {}
+
+do_test 2.2 {
+ db eval { SELECT name, rootpage FROM sqlite_master } {
+ set r($name) $rootpage
+ }
+ db close
+ set fl [hexio_get_int [hexio_read test.db 32 4]]
+
+ hexio_write test.db [expr {($fl-1) * 1024 + 0}] 00000000
+ hexio_write test.db [expr {($fl-1) * 1024 + 4}] 00000001
+ hexio_write test.db [expr {($fl-1) * 1024 + 8}] [format %.8X $r(t1)]
+ hexio_write test.db 36 00000002
+
+ sqlite3 db test.db
+} {}
+
+do_test 2.3 {
+ list [catch {
+ db eval { SELECT * FROM t1 WHERE a IN (1, 2) } {
+ db eval {
+ INSERT INTO t2 SELECT randomblob(100) FROM t2;
+ INSERT INTO t2 SELECT randomblob(100) FROM t2;
+ INSERT INTO t2 SELECT randomblob(100) FROM t2;
+ INSERT INTO t2 SELECT randomblob(100) FROM t2;
+ INSERT INTO t2 SELECT randomblob(100) FROM t2;
+ }
+ }
+ } msg] $msg
+} {1 {database disk image is malformed}}
+
+#-------------------------------------------------------------------------
+reset_db
+
+# Initialize the database.
+#
+do_execsql_test 3.1 {
+ PRAGMA page_size=1024;
+
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
+ INSERT INTO t1 VALUES(1, 'one');
+ INSERT INTO t1 VALUES(2, 'two');
+
+ CREATE TABLE t2(c INTEGER PRAGMA KEY, d);
+ INSERT INTO t2 VALUES(1, randomblob(1100));
+} {}
+
+do_test 3.2 {
+ db eval { SELECT name, rootpage FROM sqlite_master } {
+ set r($name) $rootpage
+ }
+ db close
+
+ hexio_write test.db [expr {($r(t2)-1) * 1024 + 1020}] 00000002
+
+ sqlite3 db test.db
+} {}
+
+do_test 3.3 {
+ list [catch {
+ db eval { SELECT * FROM t1 WHERE a IN (1, 2) } {
+ db eval {
+ DELETE FROM t2 WHERE c=1;
+ }
+ }
+ } msg] $msg
+} {1 {database disk image is malformed}}
+
+finish_test
+