-C Fix\sthe\ssqliteExprImpliesExpr()\sroutine\sso\sthat\sit\srecognizes\sthat\n"(NULL\sIS\sFALSE)\sIS\sFALSE"\sdoe\snot\simplie\s"NULL\sNOT\sNULL".\nTicket\s[9080b6227fabb466]
-D 2019-08-10T15:06:03.156
+C Validate\sthe\stype,\sname,\sand\stbl_name\sfields\sof\sthe\ssqlite_master\stable\swhen\nloading\sthe\sschema,\sunless\swritable_schema\sis\sengaged.
+D 2019-08-12T00:08:07.534
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
-F src/alter.c c1b5e5639b88dcc146db326315f2dea4f7f1c599e524eeb421d544927a0b1e86
+F src/alter.c 5c3031e45e80f79d7d54c2d32dd3c44926544d4f6a478858bfe4ee3191570190
F src/analyze.c 0278dbf6dbc0be90dc5391cb020772b461d789af17c390f857a34308c7ac9858
F src/attach.c 78e986baee90cb7b83fb9eafa79c22581a8ada14030fd633b0683c95cf11213c
F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
F src/btree.c 781e4594098dca97db672e52ed17c7f063b5b65db144c0c1bf1e9818e7be1ad4
F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89
F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f
-F src/build.c 9217f26f149a9dc3383018e85167187bc256198b29ab42ee5e02bc18fc1c757c
+F src/build.c d38b82d2cc13a8a80abaae12af64c4e134a15591cb6d52d841691d3f20797d7d
F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251
F src/pcache1.c 62714cbd1b7299a6e6a27a587b66b4fd3a836a84e1181e7f96f5c34a50917848
F src/pragma.c a42d4c6040893a59b69a0c987e5ed0402730c444ee451fde9bbe6203e7f73b1d
F src/pragma.h 4a9fabff14db4487a734dfeeb4be984ce662bfdccfae16145b9c732327735e13
-F src/prepare.c 1fdf68a8add154bd1de978dde5a4819478e2576d5701b93db2c65d78c3daf1c8
+F src/prepare.c 1dcd92a57f63f7ba02ece7997c0cd36647f6ea05c05726f02d7709b18bd368ac
F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c d49679d55d3cf529bbdff8734c4ac02cedfb2fc785545b89815ddb79680b9198
F src/sqlite.h.in c6bba28018378b6b43fcf4db7e9f1a3e84b0157ff54dc22ed3977acdac88e051
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5
-F src/sqliteInt.h 9286c237c240e578eac0dac23d7a4cd030c8eb5ecb6d549ae211b288382c22fd
+F src/sqliteInt.h 10b44ee37e2ec15e36f8ec2f73f801389090d379cae564646ac622739ba50673
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e
F src/treeview.c 06e65db6ffa14dd583f90403192190dfe3855c0e3acfcbac0e82109a46e2b16c
-F src/trigger.c 563df58084fa50aaf22b13ac5b71fdb02c9ffc6f0bf5d262cfe07aade4e20b3f
+F src/trigger.c 2305271878e95addc1c01361e5e8e342e87cba5efefdd7d3032687e5d67e05d1
F src/update.c 3cb9150d2cf661d938e2f1b1749945f3faa767f88febdb739ab1793bbf895ff2
F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507
F src/util.c fffdfa627be74d69ef425f92db124e7148af449bb8a3286e79577c42bca84061
F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf
-F src/vdbe.c d0c302d9f58adfbb1f5fd3542cb49ac02a8cc1375808d2a4dcacdc2a8f1fd64b
+F src/vdbe.c 1041610254502572bcc79ce6f61d9364fb93c154a4935fbaeaa7fd2e158e5205
F src/vdbe.h 3f2b571e702e77e6bf031f0236e554aedfae643e991f69000320f481408455cf
F src/vdbeInt.h e95de5129124d77f01439e6635012adfaf23c0017bff47296126143cf18bd0c6
F src/vdbeapi.c 95001d0f84ee3cda344fed98ca0d7961deb4fc836b83495630d0af1f7cc4789e
F test/corruptI.test a17bbf54fdde78d43cf3cc34b0057719fd4a173a3d824285b67dc5257c064c7b
F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af
-F test/corruptL.test 15882a75d06de29df9ad33a3503eb0fe21efbd1afcd676949c0d82e1f4e55360
+F test/corruptL.test 865cb75ed971b72b5ee9ad9017befee6bd38794011cae69f00676d82c5a5dd69
+F test/corruptM.test 04a4061b1979283851953217e411187be79e50f5e5e3ef340c3f8e564173aae1
F test/cost.test 51f4fcaae6e78ad5a57096831259ed6c760e2ac6876836e91c00030fad385b34
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
F test/countofview.test e17d6e6688cf74f22783c9ec6e788c0790ee4fbbaee713affd00b1ac0bb39b86
F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10
F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
-F test/dbfuzz001.test e32d14465f1c77712896fda6a1ccc0f037b481c191c1696a9c44f6c9e4964faf
+F test/dbfuzz001.test 42aad1dcef6219fbee86a9b7d08832c9bbb2e41508f6f128ae91745927276292
F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee
F test/dbfuzz2.c c2c9cb40082a77b7e95ffb8b2da1e93322efadfb1c8c1e0001c95a0af1e156c2
F test/dbpage.test 650234ba683b9d82b899c6c51439819787e7609f17a0cc40e0080a7b6443bc38
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 3c690b2b05b7338f3325c50a0750c6023e1173afa4388e836ecb2cc49f19a0ac
-R 3a0949f6ed843046decb4932366a96b4
+P da01ba4fa47c6508b31533ccd769e637af04bd37f51463372fbc6c848d892a4d
+R e233f3c1c14b81564e9774e7c104cb1c
U drh
-Z 90179c1f86c2ec8e084fc171c5a0f968
+Z 900804f532f967b21532d61caa969e9b
-da01ba4fa47c6508b31533ccd769e637af04bd37f51463372fbc6c848d892a4d
\ No newline at end of file
+724f4df9ccc2b683f7091a3f7a8c20ee210f44d7a610cd1b4c49da1c274add08
\ No newline at end of file
if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
goto exit_rename_table;
}
- if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto
- exit_rename_table;
+ if( SQLITE_OK!=sqlite3CheckObjectName(pParse,zName,"table",zName) ){
+ goto exit_rename_table;
}
#ifndef SQLITE_OMIT_VIEW
** trigger). All names are legal except those that begin with the string
** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
** is reserved for internal use.
+**
+** When parsing the sqlite_master table, this routine also checks to
+** make sure the "type", "name", and "tbl_name" columns are consistent
+** with the SQL.
*/
-int sqlite3CheckObjectName(Parse *pParse, const char *zName){
- if( !pParse->db->init.busy && pParse->nested==0
- && sqlite3WritableSchema(pParse->db)==0
- && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
- sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
- return SQLITE_ERROR;
+int sqlite3CheckObjectName(
+ Parse *pParse, /* Parsing context */
+ const char *zName, /* Name of the object to check */
+ const char *zType, /* Type of this object */
+ const char *zTblName /* Parent table name for triggers and indexes */
+){
+ sqlite3 *db = pParse->db;
+ if( sqlite3WritableSchema(db) || db->init.imposterTable ){
+ /* Skip these error checks for writable_schema=ON */
+ return SQLITE_OK;
+ }
+ if( db->init.busy ){
+ if( sqlite3_stricmp(zType, db->init.azInit[0])
+ || sqlite3_stricmp(zName, db->init.azInit[1])
+ || sqlite3_stricmp(zTblName, db->init.azInit[2])
+ ){
+ sqlite3ErrorMsg(pParse, ""); /* corruptSchema() will supply the error */
+ return SQLITE_ERROR;
+ }
+ }else{
+ if( pParse->nested==0
+ && 0==sqlite3StrNICmp(zName, "sqlite_", 7)
+ ){
+ sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s",
+ zName);
+ return SQLITE_ERROR;
+ }
}
return SQLITE_OK;
}
}
pParse->sNameToken = *pName;
if( zName==0 ) return;
- if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
+ if( sqlite3CheckObjectName(pParse, zName, isView?"view":"table", zName) ){
goto begin_table_error;
}
if( db->init.iDb==1 ) isTemp = 1;
zName = sqlite3NameFromToken(db, pName);
if( zName==0 ) goto exit_create_index;
assert( pName->z!=0 );
- if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
+ if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName,"index",pTab->zName) ){
goto exit_create_index;
}
if( !IN_RENAME_OBJECT ){
**
** Each callback contains the following information:
**
-** argv[0] = name of thing being created
-** argv[1] = root page number for table or index. 0 for trigger or view.
-** argv[2] = SQL text for the CREATE statement.
+** argv[0] = type of object: "table", "index", "trigger", or "view".
+** argv[1] = name of thing being created
+** argv[2] = associated table if an index or trigger
+** argv[3] = root page number for table or index. 0 for trigger or view.
+** argv[4] = SQL text for the CREATE statement.
**
*/
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
sqlite3 *db = pData->db;
int iDb = pData->iDb;
- assert( argc==3 );
+ assert( argc==5 );
UNUSED_PARAMETER2(NotUsed, argc);
assert( sqlite3_mutex_held(db->mutex) );
DbClearProperty(db, iDb, DB_Empty);
pData->nInitRow++;
if( db->mallocFailed ){
- corruptSchema(pData, argv[0], 0);
+ corruptSchema(pData, argv[1], 0);
return 1;
}
assert( iDb>=0 && iDb<db->nDb );
if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
- if( argv[1]==0 ){
- corruptSchema(pData, argv[0], 0);
- }else if( sqlite3_strnicmp(argv[2],"create ",7)==0 ){
+ if( argv[3]==0 ){
+ corruptSchema(pData, argv[1], 0);
+ }else if( sqlite3_strnicmp(argv[4],"create ",7)==0 ){
/* Call the parser to process a CREATE TABLE, INDEX or VIEW.
** But because db->init.busy is set to 1, no VDBE code is generated
** or executed. All the parser does is build the internal data
assert( db->init.busy );
db->init.iDb = iDb;
- db->init.newTnum = sqlite3Atoi(argv[1]);
+ db->init.newTnum = sqlite3Atoi(argv[3]);
db->init.orphanTrigger = 0;
- TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0);
+ db->init.azInit = argv;
+ TESTONLY(rcp = ) sqlite3_prepare(db, argv[4], -1, &pStmt, 0);
rc = db->errCode;
assert( (rc&0xFF)==(rcp&0xFF) );
db->init.iDb = saved_iDb;
if( rc==SQLITE_NOMEM ){
sqlite3OomFault(db);
}else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
- corruptSchema(pData, argv[0], sqlite3_errmsg(db));
+ corruptSchema(pData, argv[1], sqlite3_errmsg(db));
}
}
}
sqlite3_finalize(pStmt);
- }else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){
- corruptSchema(pData, argv[0], 0);
+ }else if( argv[1]==0 || (argv[4]!=0 && argv[4][0]!=0) ){
+ corruptSchema(pData, argv[1], 0);
}else{
/* If the SQL column is blank it means this is an index that
** was created to be the PRIMARY KEY or to fulfill a UNIQUE
** to do here is record the root page number for that index.
*/
Index *pIndex;
- pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zDbSName);
+ pIndex = sqlite3FindIndex(db, argv[1], db->aDb[iDb].zDbSName);
if( pIndex==0
- || sqlite3GetInt32(argv[1],&pIndex->tnum)==0
+ || sqlite3GetInt32(argv[3],&pIndex->tnum)==0
|| pIndex->tnum<2
|| sqlite3IndexHasDuplicateRootPage(pIndex)
){
- corruptSchema(pData, argv[0], pIndex?"invalid rootpage":"orphan index");
+ corruptSchema(pData, argv[1], pIndex?"invalid rootpage":"orphan index");
}
}
return 0;
int size;
#endif
Db *pDb;
- char const *azArg[4];
+ char const *azArg[6];
int meta[5];
InitData initData;
const char *zMasterName;
** table name will be inserted automatically by the parser so we can just
** use the abbreviation "x" here. The parser will also automatically tag
** the schema table as read-only. */
- azArg[0] = zMasterName = SCHEMA_TABLE(iDb);
- azArg[1] = "1";
- azArg[2] = "CREATE TABLE x(type text,name text,tbl_name text,"
+ azArg[0] = "table";
+ azArg[1] = zMasterName = SCHEMA_TABLE(iDb);
+ azArg[2] = azArg[1];
+ azArg[3] = "1";
+ azArg[4] = "CREATE TABLE x(type text,name text,tbl_name text,"
"rootpage int,sql text)";
- azArg[3] = 0;
+ azArg[5] = 0;
initData.db = db;
initData.iDb = iDb;
initData.rc = SQLITE_OK;
initData.pzErrMsg = pzErrMsg;
initData.mInitFlags = mFlags;
initData.nInitRow = 0;
- sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
+ sqlite3InitCallback(&initData, 5, (char **)azArg, 0);
if( initData.rc ){
rc = initData.rc;
goto error_out;
{
char *zSql;
zSql = sqlite3MPrintf(db,
- "SELECT name, rootpage, sql FROM \"%w\".%s ORDER BY rowid",
+ "SELECT*FROM\"%w\".%s ORDER BY rowid",
db->aDb[iDb].zDbSName, zMasterName);
#ifndef SQLITE_OMIT_AUTHORIZATION
{
unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */
unsigned imposterTable : 1; /* Building an imposter table */
unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */
+ char **azInit; /* "type", "name", and "tbl_name" columns */
} init;
int nVdbeActive; /* Number of VDBEs currently running */
int nVdbeRead; /* Number of active VDBEs that read or write */
Expr *sqlite3ExprSkipCollate(Expr*);
int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3WritableSchema(sqlite3*);
-int sqlite3CheckObjectName(Parse *, const char *);
+int sqlite3CheckObjectName(Parse*, const char*,const char*,const char*);
void sqlite3VdbeSetChanges(sqlite3 *, int);
int sqlite3AddInt64(i64*,i64);
int sqlite3SubInt64(i64*,i64);
/* Check that the trigger name is not reserved and that no trigger of the
** specified name exists */
zName = sqlite3NameFromToken(db, pName);
- if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
+ if( zName==0 ){
+ assert( db->mallocFailed );
+ goto trigger_cleanup;
+ }
+ if( sqlite3CheckObjectName(pParse, zName, "trigger", pTab->zName) ){
goto trigger_cleanup;
}
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
initData.pzErrMsg = &p->zErrMsg;
initData.mInitFlags = 0;
zSql = sqlite3MPrintf(db,
- "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
+ "SELECT*FROM\"%w\".%s WHERE %s ORDER BY rowid",
db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
if( zSql==0 ){
rc = SQLITE_NOMEM_BKPT;
}]} {}
do_execsql_test 2.1 {
+ PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking
INSERT INTO t1(b) VALUES(X'a0fee3669f9fddefc5cba913e4225d4b6ce2b04f26b87fad3ee6f9b7d90a1ea62a169bf41e5d32707a6ca5c3d05e4bde05c9d89eaaa8c50e74333d2e9fcd7dfe95528a3a016aac1102d825c5cd70cf99d8a88e0ea7f798d4334386518b7ad359beb168b93aba059a2a3bd93112d65b44c12b9904ea786b204d80531cdf0504bf9b203dbe927061974caf7b9f30cbc3397b61f802e732012a6663d41c3607d6f1c0dbcfd489adac05ca500c0b04439d894cd93a840159225ef73b627e178b9f84b3ffe66cf22a963a8368813ff7961fc47f573211ccec95e0220dcbb3bf429f4a50ba54d7a53784ac51bfef346e6ac8ae0d0e7c3175946e62ba2b');
}
}]} {}
do_catchsql_test 4.1 {
+ PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking
INSERT INTO t3 SELECT * FROM t2;
} {1 {database disk image is malformed}}
| 3872: 75 65 6e 63 65 04 43 52 45 41 54 45 20 54 41 42 uence.CREATE TAB
| 3888: 4c 45 20 73 71 6c 69 74 65 5f 73 65 71 75 65 6e LE sqlite_sequen
| 3904: 63 65 28 6e 61 6d 65 2c 73 65 71 29 81 04 01 07 ce(name,seq)....
-| 3920: 17 11 11 01 81 73 74 61 c2 6c 65 74 31 74 31 02 .....sta.let1t1.
+| 3920: 17 11 11 01 81 73 74 61 62 6c 65 74 31 74 31 02 .....stablet1t1.
| 3936: 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 31 28 CREATE TABLE t1(
| 3952: 61 20 52 45 41 4c 20 4e 4f 54 20 4e 55 4c 4c 20 a REAL NOT NULL
| 3968: 44 45 46 41 55 4c 54 28 32 35 2b 33 32 29 2c 62 DEFAULT(25+32),b
do_catchsql_test 8.1 {
+ PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking
INSERT INTO t3 SELECT * FROM t2;
} {1 {database disk image is malformed}}
}]} {}
do_catchsql_test 10.1 {
+ PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking
SELECT * FROM t1 WHERE a<='2019-05-09' ORDER BY a DESC;
} {1 {database disk image is malformed}}
}]} {}
do_catchsql_test 11.1 {
+ PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking
DELETE FROM t3 WHERE x IN (SELECT x FROM t4);
} {1 {database disk image is malformed}}
--- /dev/null
+# 2019-08-12
+#
+# 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.
+#
+#***********************************************************************
+#
+# Check to ensure that the type, name, and tbl_name fields of the
+# sqlite_master table are validated and errors are reported if they
+# are inconsistent with the sql.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix corruptM
+
+# These tests deal with corrupt database files
+#
+database_may_be_corrupt
+
+db close
+forcedelete test.db
+sqlite3 db test.db
+do_execsql_test corruptM-100 {
+ CREATE TABLE t1(a,b,c);
+ INSERT INTO t1 VALUES(111,222,333);
+ CREATE INDEX i1 ON t1(b);
+ CREATE VIEW v2 AS SELECT 15,22;
+ CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN SELECT 5; END;
+ SELECT type, name, tbl_name, '|' FROM sqlite_master;
+} {table t1 t1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
+do_execsql_test corruptM-101 {
+ PRAGMA writable_schema=on;
+ UPDATE sqlite_master SET tbl_name=NULL WHERE name='t1';
+ SELECT type, name, tbl_name, '|' FROM sqlite_master;
+} {table t1 {} | index i1 t1 | view v2 v2 | trigger r1 t1 |}
+sqlite3 db2 test.db
+do_test corruptM-102 {
+ catchsql {
+ PRAGMA quick_check;
+ } db2
+} {1 {malformed database schema (t1)}}
+db2 close
+
+do_execsql_test corruptM-110 {
+ UPDATE sqlite_master SET tbl_name='tx' WHERE name='t1';
+ SELECT type, name, tbl_name, '|' FROM sqlite_master;
+} {table t1 tx | index i1 t1 | view v2 v2 | trigger r1 t1 |}
+sqlite3 db2 test.db
+do_test corruptM-111 {
+ catchsql {
+ PRAGMA quick_check;
+ } db2
+} {1 {malformed database schema (t1)}}
+db2 close
+do_execsql_test corruptM-112 {
+ UPDATE sqlite_master SET tbl_name='t1', type='tabl' WHERE name='t1';
+ SELECT type, name, tbl_name, '|' FROM sqlite_master;
+} {tabl t1 t1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
+sqlite3 db2 test.db
+do_test corruptM-113 {
+ catchsql {
+ PRAGMA quick_check;
+ } db2
+} {1 {malformed database schema (t1)}}
+db2 close
+do_execsql_test corruptM-114 {
+ UPDATE sqlite_master SET tbl_name='t9',type='table',name='t9'WHERE name='t1';
+ SELECT type, name, tbl_name, '|' FROM sqlite_master;
+} {table t9 t9 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
+sqlite3 db2 test.db
+do_test corruptM-114 {
+ catchsql {
+ PRAGMA quick_check;
+ } db2
+} {1 {malformed database schema (t9)}}
+db2 close
+
+do_execsql_test corruptM-120 {
+ UPDATE sqlite_master SET name='t1',tbl_name='T1' WHERE name='t9';
+ SELECT type, name, tbl_name, '|' FROM sqlite_master;
+} {table t1 T1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
+sqlite3 db2 test.db
+do_test corruptM-121 {
+ catchsql {
+ PRAGMA quick_check;
+ SELECT * FROM t1, v2;
+ } db2
+} {0 {ok 111 222 333 15 22}}
+db2 close
+
+do_execsql_test corruptM-130 {
+ UPDATE sqlite_master SET type='view' WHERE name='t1';
+ SELECT type, name, tbl_name, '|' FROM sqlite_master;
+} {view t1 T1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
+sqlite3 db2 test.db
+do_test corruptM-131 {
+ catchsql {
+ PRAGMA quick_check;
+ SELECT * FROM t1, v2;
+ } db2
+} {1 {malformed database schema (t1)}}
+db2 close
+
+do_execsql_test corruptM-140 {
+ UPDATE sqlite_master SET type='table', tbl_name='t1' WHERE name='t1';
+ UPDATE sqlite_master SET tbl_name='tx' WHERE name='i1';
+ SELECT type, name, tbl_name, '|' FROM sqlite_master;
+} {table t1 t1 | index i1 tx | view v2 v2 | trigger r1 t1 |}
+sqlite3 db2 test.db
+do_test corruptM-141 {
+ catchsql {
+ PRAGMA quick_check;
+ SELECT * FROM t1, v2;
+ } db2
+} {1 {malformed database schema (i1)}}
+db2 close
+
+do_execsql_test corruptM-150 {
+ UPDATE sqlite_master SET type='table', tbl_name='t1' WHERE name='i1';
+ SELECT type, name, tbl_name, '|' FROM sqlite_master;
+} {table t1 t1 | table i1 t1 | view v2 v2 | trigger r1 t1 |}
+sqlite3 db2 test.db
+do_test corruptM-151 {
+ catchsql {
+ PRAGMA quick_check;
+ SELECT * FROM t1, v2;
+ } db2
+} {1 {malformed database schema (i1)}}
+db2 close
+
+do_execsql_test corruptM-160 {
+ UPDATE sqlite_master SET type='view', tbl_name='t1' WHERE name='i1';
+ SELECT type, name, tbl_name, '|' FROM sqlite_master;
+} {table t1 t1 | view i1 t1 | view v2 v2 | trigger r1 t1 |}
+sqlite3 db2 test.db
+do_test corruptM-161 {
+ catchsql {
+ PRAGMA quick_check;
+ SELECT * FROM t1, v2;
+ } db2
+} {1 {malformed database schema (i1)}}
+db2 close
+
+do_execsql_test corruptM-170 {
+ UPDATE sqlite_master SET type='index', tbl_name='t1' WHERE name='i1';
+ UPDATE sqlite_master SET type='table', tbl_name='v2' WHERE name='v2';
+ SELECT type, name, tbl_name, '|' FROM sqlite_master;
+} {table t1 t1 | index i1 t1 | table v2 v2 | trigger r1 t1 |}
+sqlite3 db2 test.db
+do_test corruptM-171 {
+ catchsql {
+ PRAGMA quick_check;
+ SELECT * FROM t1, v2;
+ } db2
+} {1 {malformed database schema (v2)}}
+db2 close
+
+do_execsql_test corruptM-180 {
+ UPDATE sqlite_master SET type='view',name='v3',tbl_name='v3' WHERE name='v2';
+ SELECT type, name, tbl_name, '|' FROM sqlite_master;
+} {table t1 t1 | index i1 t1 | view v3 v3 | trigger r1 t1 |}
+sqlite3 db2 test.db
+do_test corruptM-181 {
+ catchsql {
+ PRAGMA quick_check;
+ SELECT * FROM t1, v2;
+ } db2
+} {1 {malformed database schema (v3)}}
+db2 close
+
+do_execsql_test corruptM-190 {
+ UPDATE sqlite_master SET type='view',name='v2',tbl_name='v2' WHERE name='v3';
+ UPDATE sqlite_master SET type='view' WHERE name='r1';
+ SELECT type, name, tbl_name, '|' FROM sqlite_master;
+} {table t1 t1 | index i1 t1 | view v2 v2 | view r1 t1 |}
+sqlite3 db2 test.db
+do_test corruptM-191 {
+ catchsql {
+ PRAGMA quick_check;
+ SELECT * FROM t1, v2;
+ } db2
+} {1 {malformed database schema (r1)}}
+db2 close
+do_execsql_test corruptM-192 {
+ UPDATE sqlite_master SET type='trigger',tbl_name='v2' WHERE name='r1';
+ SELECT type, name, tbl_name, '|' FROM sqlite_master;
+} {table t1 t1 | index i1 t1 | view v2 v2 | trigger r1 v2 |}
+sqlite3 db2 test.db
+do_test corruptM-193 {
+ catchsql {
+ PRAGMA quick_check;
+ SELECT * FROM t1, v2;
+ } db2
+} {1 {malformed database schema (r1)}}
+db2 close
+
+finish_test
| 384: 32 28 63 2c 64 29 28 05 06 17 11 11 01 3d 74 61 2(c,d)(......=ta
| 400: 62 6c 65 74 33 74 33 07 43 52 45 41 54 45 20 54 blet3t3.CREATE T
| 416: 41 42 4c 45 20 74 33 28 63 2c 78 2c 65 2c 66 29 ABLE t3(c,x,e,f)
-| 432: 28 02 06 17 11 11 01 3d 74 61 74 65 6c 03 62 74 (......=tatel.bt
+| 432: 28 02 06 17 11 11 01 3d 74 61 62 6c 65 74 32 74 (......=tablet2t
| 448: 32 32 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 22CREATE TABLE t
| 464: 32 28 63 2c 64 2c 65 2c 66 29 24 01 06 17 11 11 2(c,d,e,f)$.....
| 480: 01 35 74 61 62 6c 65 74 31 74 31 02 43 52 45 41 .5tablet1t1.CREA