mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Have the btree layer detect when a "DELETE FROM tbl" statement is clearing a database page that is still in use (due to database corruption) and report SQLITE_CORRUPT.
FossilOrigin-Name: a6fda39e81d0da98dd6b60b32e6df786f0089c1f4ac7f3a2936afd118bd04353
This commit is contained in:
16
manifest
16
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Fix\san\sassert()\sin\sfts5\sthat\scould\sfail\swith\sa\scorrupt\sdatabase.
|
C Have\sthe\sbtree\slayer\sdetect\swhen\sa\s"DELETE\sFROM\stbl"\sstatement\sis\sclearing\sa\sdatabase\spage\sthat\sis\sstill\sin\suse\s(due\sto\sdatabase\scorruption)\sand\sreport\sSQLITE_CORRUPT.
|
||||||
D 2021-10-16T13:59:08.125
|
D 2021-10-16T17:09:36.325
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@@ -490,9 +490,9 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
|
|||||||
F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d
|
F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d
|
||||||
F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d
|
F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d
|
||||||
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
||||||
F src/btree.c 35782a608c940e219a01cf9d84de55e11668a42ede3b7b2d2fb4a6edb52e97e5
|
F src/btree.c 91cc6d99b047c4d8672780ced92ad4ee45345fc92eef62f1b4193356d930f5f6
|
||||||
F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22
|
F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22
|
||||||
F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0
|
F src/btreeInt.h ee9348c4cb9077243b049edc93a82c1f32ca48baeabf2140d41362b9f9139ff7
|
||||||
F src/build.c f70d6375ea5b78daac5b1d24eab53ed7b81c3e68a17dff9581c50c0c06180e00
|
F src/build.c f70d6375ea5b78daac5b1d24eab53ed7b81c3e68a17dff9581c50c0c06180e00
|
||||||
F src/callback.c 106b585da1edd57d75fa579d823a5218e0bf37f191dbf7417eeb4a8a9a267dbc
|
F src/callback.c 106b585da1edd57d75fa579d823a5218e0bf37f191dbf7417eeb4a8a9a267dbc
|
||||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||||
@@ -808,7 +808,7 @@ F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
|
|||||||
F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af
|
F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af
|
||||||
F test/corruptL.test 7d3440831ca24ba64305583c4d4506d417d3f89f5775c0b7cc8102db078f8ff5
|
F test/corruptL.test 7d3440831ca24ba64305583c4d4506d417d3f89f5775c0b7cc8102db078f8ff5
|
||||||
F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067
|
F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067
|
||||||
F test/corruptN.test c2a96ff81386027f7d7e95858783aa36f82ba1532106969575e3c8f90903a5bb
|
F test/corruptN.test 14962dc3f5567b5722a24d166bf143bec790673476f7b0932d82609210d1becd
|
||||||
F test/cost.test b11cdbf9f11ffe8ef99c9881bf390e61fe92baf2182bad1dbe6de59a7295c576
|
F test/cost.test b11cdbf9f11ffe8ef99c9881bf390e61fe92baf2182bad1dbe6de59a7295c576
|
||||||
F test/count.test 5364003488249957750a5f15ee42ca1cd7b100b1131c2dc71fff266a1250bf55
|
F test/count.test 5364003488249957750a5f15ee42ca1cd7b100b1131c2dc71fff266a1250bf55
|
||||||
F test/countofview.test e17d6e6688cf74f22783c9ec6e788c0790ee4fbbaee713affd00b1ac0bb39b86
|
F test/countofview.test e17d6e6688cf74f22783c9ec6e788c0790ee4fbbaee713affd00b1ac0bb39b86
|
||||||
@@ -1929,7 +1929,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 8a56de5b9c6f4522000f8d991373490b67b9e9d97f03c1ca2cf32816d84789ef
|
P e99979855de937ed5ee0994b180054501400bf8776fb70acd31786d2ba1ad49a
|
||||||
R 4bcaeff59bcce0f4ef771608de87df49
|
R 3f77e71e98554900f2c6a9f0c33e3266
|
||||||
U dan
|
U dan
|
||||||
Z af80492fe37d3ad04ab438f47d1814c1
|
Z ce8477010c93ae34e562deaff5d43b53
|
||||||
|
@@ -1 +1 @@
|
|||||||
e99979855de937ed5ee0994b180054501400bf8776fb70acd31786d2ba1ad49a
|
a6fda39e81d0da98dd6b60b32e6df786f0089c1f4ac7f3a2936afd118bd04353
|
10
src/btree.c
10
src/btree.c
@@ -9549,11 +9549,12 @@ static int clearDatabasePage(
|
|||||||
}
|
}
|
||||||
rc = getAndInitPage(pBt, pgno, &pPage, 0, 0);
|
rc = getAndInitPage(pBt, pgno, &pPage, 0, 0);
|
||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
if( pPage->bBusy ){
|
if( (pBt->openFlags & BTREE_SINGLE)==0
|
||||||
|
&& sqlite3PagerPageRefcount(pPage->pDbPage)!=1
|
||||||
|
){
|
||||||
rc = SQLITE_CORRUPT_BKPT;
|
rc = SQLITE_CORRUPT_BKPT;
|
||||||
goto cleardatabasepage_out;
|
goto cleardatabasepage_out;
|
||||||
}
|
}
|
||||||
pPage->bBusy = 1;
|
|
||||||
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);
|
||||||
@@ -9580,7 +9581,6 @@ static int clearDatabasePage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleardatabasepage_out:
|
cleardatabasepage_out:
|
||||||
pPage->bBusy = 0;
|
|
||||||
releasePage(pPage);
|
releasePage(pPage);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -9659,9 +9659,9 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
|
|||||||
return SQLITE_CORRUPT_BKPT;
|
return SQLITE_CORRUPT_BKPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
|
|
||||||
if( rc ) return rc;
|
|
||||||
rc = sqlite3BtreeClearTable(p, iTable, 0);
|
rc = sqlite3BtreeClearTable(p, iTable, 0);
|
||||||
|
if( rc ) return rc;
|
||||||
|
rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
releasePage(pPage);
|
releasePage(pPage);
|
||||||
return rc;
|
return rc;
|
||||||
|
@@ -272,7 +272,6 @@ typedef struct CellInfo CellInfo;
|
|||||||
*/
|
*/
|
||||||
struct MemPage {
|
struct MemPage {
|
||||||
u8 isInit; /* True if previously initialized. MUST BE FIRST! */
|
u8 isInit; /* True if previously initialized. MUST BE FIRST! */
|
||||||
u8 bBusy; /* Prevent endless loops on corrupt database files */
|
|
||||||
u8 intKey; /* True if table b-trees. False for index b-trees */
|
u8 intKey; /* True if table b-trees. False for index b-trees */
|
||||||
u8 intKeyLeaf; /* True if the leaf of an intKey table */
|
u8 intKeyLeaf; /* True if the leaf of an intKey table */
|
||||||
Pgno pgno; /* Page number for this page */
|
Pgno pgno; /* Page number for this page */
|
||||||
|
@@ -224,5 +224,52 @@ ifcapable json1&&vtab {
|
|||||||
}
|
}
|
||||||
}; # ifcapable json1&&vtab
|
}; # ifcapable json1&&vtab
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
reset_db
|
||||||
|
|
||||||
|
do_execsql_test 6.0 {
|
||||||
|
PRAGMA page_size=1024;
|
||||||
|
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||||
|
INSERT INTO t1(b) VALUES(zeroblob(300)),(zeroblob(300)),(zeroblob(300)),(zeroblob(300));
|
||||||
|
CREATE TABLE t2(a);
|
||||||
|
CREATE TRIGGER t1tr BEFORE UPDATE ON t1 BEGIN DELETE FROM t2; END;
|
||||||
|
PRAGMA writable_schema=ON;
|
||||||
|
UPDATE sqlite_schema SET rootpage=3 WHERE rowid=2;
|
||||||
|
PRAGMA writable_schema=RESET;
|
||||||
|
INSERT INTO t2 VALUES('active'),('boomer'),('atom'),('atomic'),
|
||||||
|
('alpha channel backup abandon test aback boomer atom alpha active');
|
||||||
|
}
|
||||||
|
do_catchsql_test 6.1 {
|
||||||
|
UPDATE t1 SET b=zeroblob(299);
|
||||||
|
} {1 {database disk image is malformed}}
|
||||||
|
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 6.2 {
|
||||||
|
-- Make "t1" a large table. Large enough that the children of the root
|
||||||
|
-- node are interior nodes.
|
||||||
|
PRAGMA page_size = 1024;
|
||||||
|
PRAGMA autovacuum = 0;
|
||||||
|
CREATE TABLE t1(x);
|
||||||
|
WITH s(i) AS (
|
||||||
|
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<500
|
||||||
|
)
|
||||||
|
INSERT INTO t1 SELECT zeroblob(300) FROM s;
|
||||||
|
|
||||||
|
CREATE TABLE t2(y);
|
||||||
|
CREATE TRIGGER tr BEFORE UPDATE ON t1 BEGIN
|
||||||
|
DELETE FROM t2;
|
||||||
|
END;
|
||||||
|
|
||||||
|
-- Set the root of table t2 to 137 - the leftmost child of the root of t1.
|
||||||
|
PRAGMA writable_schema = ON;
|
||||||
|
UPDATE sqlite_schema SET rootpage = 137 WHERE name='t2';
|
||||||
|
PRAGMA writable_schema = RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_catchsql_test 6.3 {
|
||||||
|
-- Run an UPDATE on t1 that will hit a child of page 136. Have the trigger
|
||||||
|
-- clear page 136 and its children. Assert fails.
|
||||||
|
UPDATE t1 SET x='hello world' WHERE rowid=1;
|
||||||
|
} {1 {database disk image is malformed}}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
Reference in New Issue
Block a user