mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Prevent a possible infinite loop when trying to DROP a table from
a corrupt database. FossilOrigin-Name: 395bb3e677a6551b06ba96fc58c393132b93d1e8
This commit is contained in:
15
manifest
15
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Enhancements\sto\sOSTRACE\susage\sin\sthe\sWin32\sVFS.
|
C Prevent\sa\spossible\sinfinite\sloop\swhen\strying\sto\sDROP\sa\stable\sfrom\na\scorrupt\sdatabase.
|
||||||
D 2015-03-27T18:20:25.776
|
D 2015-03-30T23:43:56.191
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb
|
F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -173,7 +173,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
|||||||
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
|
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
|
||||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||||
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
||||||
F src/btree.c 4f305e554d7d207375c3e29ab0335bd5a473a125
|
F src/btree.c e565971caa0265d3cabc8b15d7017899a7814051
|
||||||
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
||||||
F src/btreeInt.h 2bfefc01875d8da066504c233ec259fcb3b2ef72
|
F src/btreeInt.h 2bfefc01875d8da066504c233ec259fcb3b2ef72
|
||||||
F src/build.c 0419bba592c22f6d00e6d57a2ca7136720d02c1a
|
F src/build.c 0419bba592c22f6d00e6d57a2ca7136720d02c1a
|
||||||
@@ -433,6 +433,7 @@ F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
|
|||||||
F test/corruptG.test 1ab3bf97ee7bdba70e0ff3ba2320657df55d1804
|
F test/corruptG.test 1ab3bf97ee7bdba70e0ff3ba2320657df55d1804
|
||||||
F test/corruptH.test 5dd4fa98c6c1ed33b178f9e8a48c4fdd3cfc9067
|
F test/corruptH.test 5dd4fa98c6c1ed33b178f9e8a48c4fdd3cfc9067
|
||||||
F test/corruptI.test 221ad8b7f0a9ac6b80fc577e73b5ad8cdea31243
|
F test/corruptI.test 221ad8b7f0a9ac6b80fc577e73b5ad8cdea31243
|
||||||
|
F test/corruptJ.test 8f584eb97b88e7b160d03edfe2f814c64e56b4ac
|
||||||
F test/cost.test 19d314526616ce4473eb4e4e450fcb94499ce318
|
F test/cost.test 19d314526616ce4473eb4e4e450fcb94499ce318
|
||||||
F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5
|
F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5
|
||||||
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
|
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
|
||||||
@@ -1247,7 +1248,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P 0ec08ba8a0fa188146b071a489908332693ba59a
|
P ab5800291e1908b5b51d912feeacf748dc9be14b
|
||||||
R 5fa56a67857aa9aa0bfe9c8eabbd7f2b
|
R 7b7ce803eb05ad2f210c6eb94fdd8e1c
|
||||||
U mistachkin
|
U drh
|
||||||
Z 22e64f81a05ea0084d0b656c0478e6e9
|
Z 53c46ef4969a0037acc3578044ba6e9e
|
||||||
|
@@ -1 +1 @@
|
|||||||
ab5800291e1908b5b51d912feeacf748dc9be14b
|
395bb3e677a6551b06ba96fc58c393132b93d1e8
|
@@ -7978,6 +7978,7 @@ static int clearDatabasePage(
|
|||||||
int i;
|
int i;
|
||||||
int hdr;
|
int hdr;
|
||||||
u16 szCell;
|
u16 szCell;
|
||||||
|
u8 hasChildren;
|
||||||
|
|
||||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||||
if( pgno>btreePagecount(pBt) ){
|
if( pgno>btreePagecount(pBt) ){
|
||||||
@@ -7986,17 +7987,19 @@ static int clearDatabasePage(
|
|||||||
|
|
||||||
rc = getAndInitPage(pBt, pgno, &pPage, 0);
|
rc = getAndInitPage(pBt, pgno, &pPage, 0);
|
||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
|
hasChildren = !pPage->leaf;
|
||||||
|
pPage->leaf = 1; /* Block looping if the database is corrupt */
|
||||||
hdr = pPage->hdrOffset;
|
hdr = pPage->hdrOffset;
|
||||||
for(i=0; i<pPage->nCell; i++){
|
for(i=0; i<pPage->nCell; i++){
|
||||||
pCell = findCell(pPage, i);
|
pCell = findCell(pPage, i);
|
||||||
if( !pPage->leaf ){
|
if( hasChildren ){
|
||||||
rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
|
rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
|
||||||
if( rc ) goto cleardatabasepage_out;
|
if( rc ) goto cleardatabasepage_out;
|
||||||
}
|
}
|
||||||
rc = clearCell(pPage, pCell, &szCell);
|
rc = clearCell(pPage, pCell, &szCell);
|
||||||
if( rc ) goto cleardatabasepage_out;
|
if( rc ) goto cleardatabasepage_out;
|
||||||
}
|
}
|
||||||
if( !pPage->leaf ){
|
if( hasChildren ){
|
||||||
rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange);
|
rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange);
|
||||||
if( rc ) goto cleardatabasepage_out;
|
if( rc ) goto cleardatabasepage_out;
|
||||||
}else if( pnChange ){
|
}else if( pnChange ){
|
||||||
|
80
test/corruptJ.test
Normal file
80
test/corruptJ.test
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
# 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
|
Reference in New Issue
Block a user