Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Avoid crashing after parsing a corrupt schema with a REUSE_SCHEMA connection. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | reuse-schema |
Files: | files | file ages | folders |
SHA3-256: |
b102148e71c0102eedbf28d9bc8ea8d9 |
User & Date: | dan 2019-02-13 18:29:49.853 |
Context
2019-02-13
| ||
19:17 | Fix for sqlite3_table_column_metadata() on REUSE_SCHEMA databases. (check-in: 53220ad780 user: dan tags: reuse-schema) | |
18:29 | Avoid crashing after parsing a corrupt schema with a REUSE_SCHEMA connection. (check-in: b102148e71 user: dan tags: reuse-schema) | |
15:51 | Fix a problem with the incrblob API and reusable schemas. (check-in: 34f0f96f47 user: dan tags: reuse-schema) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
277 278 279 280 281 282 283 284 285 286 287 288 289 290 | ** Return TRUE if zTable is the name of the system table that stores the ** list of users and their access credentials. */ int sqlite3UserAuthTable(const char *zTable){ return sqlite3_stricmp(zTable, "sqlite_user")==0; } #endif /* ** Locate the in-memory structure that describes a particular database ** table given the name of that table and (optionally) the name of the ** database containing the table. Return NULL if not found. ** ** If zDatabase is 0, all databases are searched for the table and the | > > > > > > > > > > > > > > > > | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | ** Return TRUE if zTable is the name of the system table that stores the ** list of users and their access credentials. */ int sqlite3UserAuthTable(const char *zTable){ return sqlite3_stricmp(zTable, "sqlite_user")==0; } #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 ** database containing the table. Return NULL if not found. ** ** If zDatabase is 0, all databases are searched for the table and the |
︙ | ︙ | |||
307 308 309 310 311 312 313 | return 0; } #endif while(1){ 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 ){ | | < < < < < < < | < < | 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | return 0; } #endif while(1){ 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; assert( sqlite3SchemaMutexHeld(db, j, 0) ); bUnload = loadReusableSchema(db, j); p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); if( p ) return p; if( bUnload ){ sqlite3SchemaRelease(db, j); } } } |
︙ | ︙ | |||
375 376 377 378 379 380 381 | ** can be an eponymous virtual table. */ if( pParse->disableVtab==0 ){ Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ pMod = sqlite3PragmaVtabRegister(db, zName); } if( pMod ){ | | < < < < < | 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | ** can be an eponymous virtual table. */ if( pParse->disableVtab==0 ){ Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ pMod = sqlite3PragmaVtabRegister(db, zName); } if( pMod ){ loadReusableSchema(db, 0); if( sqlite3VtabEponymousTableInit(pParse, pMod) ){ return pMod->pEpoTab; } } } #endif if( flags & LOCATE_NOERR ) return 0; |
︙ | ︙ |
Changes to src/callback.c.
︙ | ︙ | |||
524 525 526 527 528 529 530 | ** database iDb. ** ** If an OOM error occurs while disconnecting from a schema-pool, ** the db->mallocFailed flag is set. */ void sqlite3SchemaClearOrDisconnect(sqlite3 *db, int iDb){ Db *pDb = &db->aDb[iDb]; | | | 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 | ** database iDb. ** ** If an OOM error occurs while disconnecting from a schema-pool, ** the db->mallocFailed flag is set. */ void sqlite3SchemaClearOrDisconnect(sqlite3 *db, int iDb){ Db *pDb = &db->aDb[iDb]; if( IsReuseSchema(db) && iDb!=1 && pDb->pSPool ){ sqlite3SchemaDisconnect(db, iDb, 1); }else{ sqlite3SchemaClear(pDb->pSchema); } } /* |
︙ | ︙ |
Changes to src/vdbeblob.c.
︙ | ︙ | |||
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | if( !sqlite3SafetyCheckOk(db) || zTable==0 ){ return SQLITE_MISUSE_BKPT; } #endif wrFlag = !!wrFlag; /* wrFlag = (wrFlag ? 1 : 0); */ sqlite3_mutex_enter(db->mutex); bUnlock = sqlite3LockReusableSchema(db); pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); do { memset(&sParse, 0, sizeof(Parse)); if( !pBlob ) goto blob_open_out; sParse.db = db; sqlite3DbFree(db, zErr); zErr = 0; sqlite3BtreeEnterAll(db); pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb); if( pTab && IsVirtual(pTab) ){ pTab = 0; | > > | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | if( !sqlite3SafetyCheckOk(db) || zTable==0 ){ return SQLITE_MISUSE_BKPT; } #endif wrFlag = !!wrFlag; /* wrFlag = (wrFlag ? 1 : 0); */ sqlite3_mutex_enter(db->mutex); assert( db->pParse==0 ); bUnlock = sqlite3LockReusableSchema(db); pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); do { memset(&sParse, 0, sizeof(Parse)); if( !pBlob ) goto blob_open_out; sParse.db = db; db->pParse = &sParse; sqlite3DbFree(db, zErr); zErr = 0; sqlite3BtreeEnterAll(db); pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb); if( pTab && IsVirtual(pTab) ){ pTab = 0; |
︙ | ︙ | |||
329 330 331 332 333 334 335 336 337 338 339 340 341 342 | if( db->mallocFailed ){ goto blob_open_out; } rc = blobSeekToRow(pBlob, iRow, &zErr); } while( (++nAttempt)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA ); blob_open_out: sqlite3UnlockReusableSchema(db, bUnlock); if( rc==SQLITE_OK && db->mallocFailed==0 ){ *ppBlob = (sqlite3_blob *)pBlob; }else{ if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); sqlite3DbFree(db, pBlob); } | > | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | if( db->mallocFailed ){ goto blob_open_out; } rc = blobSeekToRow(pBlob, iRow, &zErr); } 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; }else{ if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); sqlite3DbFree(db, pBlob); } |
︙ | ︙ |
Changes to test/reuse3.test.
︙ | ︙ | |||
63 64 65 66 67 68 69 | SELECT * FROM t2 } {1 4} do_execsql_test 1.9 { SELECT * FROM v1 } {1 2 3 4 5 6} | > > > > > > > > > > > | > > > > > > > > > | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | SELECT * FROM t2 } {1 4} do_execsql_test 1.9 { SELECT * FROM v1 } {1 2 3 4 5 6} #------------------------------------------------------------------------- # 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 |