A testcase causing Assertion `idx>=0 && idx<pPage->nCell' failed
(1.1) By Jingzhou Fu (fuboat) on 2022-01-02 06:51:38 edited from 1.0 [source]
System Information:
compile-time options: CC=clang-12 ./configure --enable-debug
sqlite3_sourceid: 2022-01-01 22:55:31 e199a851e316bd471bfc54204b8c250d3ae93b829261214158a2c74acad4093e
output: sqlite3.c:72510: dropCell: Assertion `idx>=0 && idx<pPage->nCell' failed.
PoC:
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;
DROP table "t2";
PRAGMA foreign_keys = OFF;
PRAGMA foreign_keys = on;
CREATE TABLE t2(c REFERENCES t1(a) , d);
INSERT INTO t2 VALUES(NULL, 4);
UPDATE t1 SET a = 1;
(2) By Richard Hipp (drh) on 2022-01-02 14:03:52 in reply to 1.1 [link] [source]
Thanks for the bug report.
This is just a bad assert(). It should not affect production builds.
Nevertheless, the assert() that failed indicates that code was getting "close to the edge" so to speak. So in addition to fixing the assert(), I also added some extra defenses against corrupt databases. And I might be adding still more defenses in subsequent check-ins.
The fix for this is on trunk.