]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Avoid crashing after parsing a corrupt schema with a REUSE_SCHEMA connection.
authordan <dan@noemail.net>
Wed, 13 Feb 2019 18:29:49 +0000 (18:29 +0000)
committerdan <dan@noemail.net>
Wed, 13 Feb 2019 18:29:49 +0000 (18:29 +0000)
FossilOrigin-Name: b102148e71c0102eedbf28d9bc8ea8d9bd742eac45ee7f1b08ece60bcdab5036

manifest
manifest.uuid
src/build.c
src/callback.c
src/vdbeblob.c
test/reuse3.test

index 2229d6dcaf003bfcdbfd849e9c153b8344ae547b..c06a0550a34924e72104cc41680f3e4fdb836575 100644 (file)
--- 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
index 755e6629200c32c7b92c75d1a2b61c1b8a6b1bb6..b7bac1769a1635d56f4d5425c260230669bdc225 100644 (file)
@@ -1 +1 @@
-34f0f96f47040df1e305ac9fd4664c5ed4246580e22a00573c73d6528a5725b5
\ No newline at end of file
+b102148e71c0102eedbf28d9bc8ea8d9bd742eac45ee7f1b08ece60bcdab5036
\ No newline at end of file
index 3960fa2fb166d0a7c52713081f48df1bbcad1e32..345986ca17225ec46f246fe9099b7e9763c062f1 100644 (file)
@@ -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; i<db->nDb; 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;
         }
index fbb452108a02e95d2b04b1b59bdfa1491f01a43b..879c3dff3bde068a91c74abe96fef0b6f974cc4a 100644 (file)
@@ -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);
index ed90e10f2b9b648ab5324c47f0ffa6689d195d23..a4ecbe83a1d0854d63e69964cf1afa2351e9d9bc 100644 (file)
@@ -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)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA );
 
 blob_open_out:
+  db->pParse = 0;
   sqlite3UnlockReusableSchema(db, bUnlock);
   if( rc==SQLITE_OK && db->mallocFailed==0 ){
     *ppBlob = (sqlite3_blob *)pBlob;
index 4e00907cb71ba9559685050934ec11065f906273..4db0caa74552cb1777ff75020aebe66443ee3d0e 100644 (file)
@@ -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