From: dan Date: Wed, 13 Feb 2019 18:29:49 +0000 (+0000) Subject: Avoid crashing after parsing a corrupt schema with a REUSE_SCHEMA connection. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9d65677e5735f3407fa0b6c2741a2642955326d9;p=thirdparty%2Fsqlite.git Avoid crashing after parsing a corrupt schema with a REUSE_SCHEMA connection. FossilOrigin-Name: b102148e71c0102eedbf28d9bc8ea8d9bd742eac45ee7f1b08ece60bcdab5036 --- diff --git a/manifest b/manifest index 2229d6dcaf..c06a0550a3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sthe\sincrblob\sAPI\sand\sreusable\sschemas. -D 2019-02-13T15:51:07.091 +C Avoid\scrashing\safter\sparsing\sa\scorrupt\sschema\swith\sa\sREUSE_SCHEMA\sconnection. +D 2019-02-13T18:29:49.853 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 56456706c4da271309914c756c9c8ea537685f1c79f8785afa72f968d6810482 @@ -458,8 +458,8 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 18046bf14f0e3fa294ef3f7c2dc30ca7e95f3ac11ec222ad906e40b150051bde F src/btree.h 63b94fb38ce571c15eb6a3661815561b501d23d5948b2d1e951fbd7a2d04e8d3 F src/btreeInt.h cd82f0f08886078bf99b29e1a7045960b1ca5d9d5829c38607e1299c508eaf00 -F src/build.c 98beafec3e352c5f1d5883b7a764854cf3f8bb9f42fdc89ae9b90ff73ce3d9b5 -F src/callback.c eaa832c5b8b6f64e9ca78f61c3d9034a6a4d697ae426dbbc7de1c760045f6dc3 +F src/build.c c6b40555c68a157d85b4fbd0e08842ce87a374aad685341b7b6fa05d87770ffb +F src/callback.c 341911a87bb310091f8ed9e1c53c1e9c001cae296ae011d88b0c8eb64b5a9b22 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957 @@ -591,7 +591,7 @@ F src/vdbe.h 323218c4bfd64c719ba85d05fbc87cdd126991cadb39e73ccac7b59f30c3d53e F src/vdbeInt.h a76d5eed62c76bcd8de7afd3147fac1bc40c5a870582664bcd7d071ef437c37f F src/vdbeapi.c 57a2d794a8833f269b878dbc24e955369bdb379af6c4e93ebc5ce1a20fa3daf4 F src/vdbeaux.c 2f4fefdf74c484193de632c3c417c5886512f7a57f69a65dbdb858a58bc3f55a -F src/vdbeblob.c 6e362fafab5c537f247424fefade58d7eb938e60ef13817590031eb64cbb690f +F src/vdbeblob.c 08e58c6bef990008b8c2dbad4c99c56d3b622ee79433004484cce29b536e2ab9 F src/vdbemem.c 3e89e087df928eba80e520824078dc563c579a0848b1557ac36845ec14392923 F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392 @@ -1228,7 +1228,7 @@ F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5e F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/reuse1.test 5eee2efc7ee559fa9bdd214e35b351d5a949ad466c1671c256fee1f133e7eeea F test/reuse2.test 7d9e63de7909711a970b848f1f068d820c0f8e61f12b68ee5ec11a019beba20e -F test/reuse3.test 4eab99d5762c74422f24664680f4e482edd79f593919ffa3f18368735ee3b944 +F test/reuse3.test c9cc919586a6005d7ed19cf5ab8eb8c618f35dab5ed5ef8526f37815888c4973 F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa F test/rollback2.test bc868d57899dc6972e2b4483faae0e03365a0556941474eec487ae21d8d38bb6 F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a @@ -1808,7 +1808,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 219b39e149a0334b577e094e066e1ca2fe686b408468e9f196611490f3a82810 -R 9047b65c4afb92b6d121e7343cd6282b +P 34f0f96f47040df1e305ac9fd4664c5ed4246580e22a00573c73d6528a5725b5 +R d8eb2edb5addad96a4a6091026ccb42a U dan -Z 8146267c5361e666d0319bd1ff8f7427 +Z 700b51cb945ffefb19ca39cbc0189c26 diff --git a/manifest.uuid b/manifest.uuid index 755e662920..b7bac1769a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -34f0f96f47040df1e305ac9fd4664c5ed4246580e22a00573c73d6528a5725b5 \ No newline at end of file +b102148e71c0102eedbf28d9bc8ea8d9bd742eac45ee7f1b08ece60bcdab5036 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 3960fa2fb1..345986ca17 100644 --- a/src/build.c +++ b/src/build.c @@ -282,6 +282,22 @@ int sqlite3UserAuthTable(const char *zTable){ } #endif +static int loadReusableSchema(sqlite3 *db, int iDb){ + if( IsReuseSchema(db) + && DbHasProperty(db, iDb, DB_SchemaLoaded)==0 + && (db->init.busy==0 || (iDb!=1 && db->init.iDb==1)) + ){ + char *zDummy = 0; + struct sqlite3InitInfo sv = db->init; + memset(&db->init, 0, sizeof(struct sqlite3InitInfo)); + sqlite3InitOne(db, iDb, &zDummy, 0); + sqlite3_free(zDummy); + db->init = sv; + return (iDb!=1); + } + return 0; +} + /* ** Locate the in-memory structure that describes a particular database ** table given the name of that table and (optionally) the name of the @@ -311,18 +327,9 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ for(i=OMIT_TEMPDB; inDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){ - int bUnload = 0; + int bUnload; assert( sqlite3SchemaMutexHeld(db, j, 0) ); - if( IsReuseSchema(db) - && DbHasProperty(db, j, DB_SchemaLoaded)==0 - && (db->init.busy==0 || (j!=1 && db->init.iDb==1)) - ){ - struct sqlite3InitInfo sv = db->init; - memset(&db->init, 0, sizeof(struct sqlite3InitInfo)); - sqlite3InitOne(db, j, 0, 0); - bUnload = (j!=1); - db->init = sv; - } + bUnload = loadReusableSchema(db, j); p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); if( p ) return p; if( bUnload ){ @@ -379,12 +386,7 @@ Table *sqlite3LocateTable( pMod = sqlite3PragmaVtabRegister(db, zName); } if( pMod ){ - if( IsReuseSchema(db) - && DbHasProperty(db, 0, DB_SchemaLoaded)==0 - && db->init.busy==0 - ){ - sqlite3InitOne(db, 0, 0, 0); - } + loadReusableSchema(db, 0); if( sqlite3VtabEponymousTableInit(pParse, pMod) ){ return pMod->pEpoTab; } diff --git a/src/callback.c b/src/callback.c index fbb452108a..879c3dff3b 100644 --- a/src/callback.c +++ b/src/callback.c @@ -528,7 +528,7 @@ void sqlite3SchemaClear(void *p){ */ void sqlite3SchemaClearOrDisconnect(sqlite3 *db, int iDb){ Db *pDb = &db->aDb[iDb]; - if( IsReuseSchema(db) && iDb!=1 ){ + if( IsReuseSchema(db) && iDb!=1 && pDb->pSPool ){ sqlite3SchemaDisconnect(db, iDb, 1); }else{ sqlite3SchemaClear(pDb->pSchema); diff --git a/src/vdbeblob.c b/src/vdbeblob.c index ed90e10f2b..a4ecbe83a1 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -148,6 +148,7 @@ int sqlite3_blob_open( wrFlag = !!wrFlag; /* wrFlag = (wrFlag ? 1 : 0); */ sqlite3_mutex_enter(db->mutex); + assert( db->pParse==0 ); bUnlock = sqlite3LockReusableSchema(db); pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); @@ -155,6 +156,7 @@ int sqlite3_blob_open( memset(&sParse, 0, sizeof(Parse)); if( !pBlob ) goto blob_open_out; sParse.db = db; + db->pParse = &sParse; sqlite3DbFree(db, zErr); zErr = 0; @@ -333,6 +335,7 @@ int sqlite3_blob_open( } while( (++nAttempt)pParse = 0; sqlite3UnlockReusableSchema(db, bUnlock); if( rc==SQLITE_OK && db->mallocFailed==0 ){ *ppBlob = (sqlite3_blob *)pBlob; diff --git a/test/reuse3.test b/test/reuse3.test index 4e00907cb7..4db0caa745 100644 --- a/test/reuse3.test +++ b/test/reuse3.test @@ -67,6 +67,26 @@ do_execsql_test 1.9 { SELECT * FROM v1 } {1 2 3 4 5 6} -finish_test +#------------------------------------------------------------------------- +# Test error messages when parsing the schema with a REUSE_SCHEMA +# connection. +reset_db +do_execsql_test 2.0 { + CREATE TABLE x1(a, b, c); + CREATE TABLE y1(d, e, f); + PRAGMA writable_schema = 1; + UPDATE sqlite_master SET sql = 'CREATE TBL y1(d, e, f)' WHERE name = 'y1'; +} +db close +sqlite3 db test.db -reuse-schema 1 +do_catchsql_test 2.1 { + SELECT * FROM x1; +} {1 {no such table: x1}} + +do_catchsql_test 2.2 { + SELECT * FROM x1; +} {1 {no such table: x1}} + +finish_test