-C Enhancements\sto\sOSTRACE\susage\sin\sthe\sWin32\sVFS.
-D 2015-03-27T18:20:25.776
+C Prevent\sa\spossible\sinfinite\sloop\swhen\strying\sto\sDROP\sa\stable\sfrom\na\scorrupt\sdatabase.
+D 2015-03-30T23:43:56.191
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
-F src/btree.c 4f305e554d7d207375c3e29ab0335bd5a473a125
+F src/btree.c e565971caa0265d3cabc8b15d7017899a7814051
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
F src/btreeInt.h 2bfefc01875d8da066504c233ec259fcb3b2ef72
F src/build.c 0419bba592c22f6d00e6d57a2ca7136720d02c1a
F test/corruptG.test 1ab3bf97ee7bdba70e0ff3ba2320657df55d1804
F test/corruptH.test 5dd4fa98c6c1ed33b178f9e8a48c4fdd3cfc9067
F test/corruptI.test 221ad8b7f0a9ac6b80fc577e73b5ad8cdea31243
+F test/corruptJ.test 8f584eb97b88e7b160d03edfe2f814c64e56b4ac
F test/cost.test 19d314526616ce4473eb4e4e450fcb94499ce318
F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 0ec08ba8a0fa188146b071a489908332693ba59a
-R 5fa56a67857aa9aa0bfe9c8eabbd7f2b
-U mistachkin
-Z 22e64f81a05ea0084d0b656c0478e6e9
+P ab5800291e1908b5b51d912feeacf748dc9be14b
+R 7b7ce803eb05ad2f210c6eb94fdd8e1c
+U drh
+Z 53c46ef4969a0037acc3578044ba6e9e
-ab5800291e1908b5b51d912feeacf748dc9be14b
\ No newline at end of file
+395bb3e677a6551b06ba96fc58c393132b93d1e8
\ No newline at end of file
int i;
int hdr;
u16 szCell;
+ u8 hasChildren;
assert( sqlite3_mutex_held(pBt->mutex) );
if( pgno>btreePagecount(pBt) ){
rc = getAndInitPage(pBt, pgno, &pPage, 0);
if( rc ) return rc;
+ hasChildren = !pPage->leaf;
+ pPage->leaf = 1; /* Block looping if the database is corrupt */
hdr = pPage->hdrOffset;
for(i=0; i<pPage->nCell; i++){
pCell = findCell(pPage, i);
- if( !pPage->leaf ){
+ if( hasChildren ){
rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
if( rc ) goto cleardatabasepage_out;
}
rc = clearCell(pPage, pCell, &szCell);
if( rc ) goto cleardatabasepage_out;
}
- if( !pPage->leaf ){
+ if( hasChildren ){
rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange);
if( rc ) goto cleardatabasepage_out;
}else if( pnChange ){
--- /dev/null
+# 2015-03-30
+#
+# 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.
+#
+#***********************************************************************
+#
+# Corruption consisting of a database page that thinks it is a child
+# of itself.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix corruptJ
+
+if {[permutation]=="mmap"} {
+ finish_test
+ return
+}
+
+# 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;
+ PRAGMA auto_vacuum=0;
+ CREATE TABLE t1(a,b);
+ WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<10)
+ INSERT INTO t1(a,b) SELECT i, zeroblob(700) FROM c;
+} {}
+db close
+
+# Corrupt the root page of the t1 table such that the left-child pointer
+# for the very first cell points back to the root. Then try to DROP the
+# table. The clearDatabasePage() routine should not loop.
+#
+do_test 1.2 {
+ hexio_write test.db [expr {2*1024-2}] 02
+ sqlite3 db test.db
+ catchsql { DROP TABLE t1 }
+} {1 {database disk image is malformed}}
+
+# Similar test using a WITHOUT ROWID table
+#
+do_test 2.1 {
+ db close
+ forcedelete test.db
+ sqlite3 db test.db
+ db eval {
+ PRAGMA page_size=1024;
+ PRAGMA auto_vacuum=0;
+ CREATE TABLE t1(a,b,PRIMARY KEY(a,b)) WITHOUT ROWID;
+ WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<100)
+ INSERT INTO t1(a,b) SELECT i, zeroblob(200) FROM c;
+ }
+} {}
+
+# The table is three levels deep. Corrupt the left child of an intermediate
+# page so that it points back to the root page.
+#
+do_test 2.2 {
+ db close
+ hexio_read test.db [expr {9*1024+391}] 8
+} {00000008814D0401}
+do_test 2.2b {
+ hexio_write test.db [expr {9*1024+391}] 00000002
+ sqlite3 db test.db
+ catchsql { DROP TABLE t1 }
+} {0 {}}
+
+finish_test