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 | SQL 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 |
Wiki: | reuse-schema |
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 ... 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 ... 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 |
** 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 ................................................................................ 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 = 0; 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; } p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); if( p ) return p; if( bUnload ){ sqlite3SchemaRelease(db, j); } } } ................................................................................ ** 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 ){ if( IsReuseSchema(db) && DbHasProperty(db, 0, DB_SchemaLoaded)==0 && db->init.busy==0 ){ sqlite3InitOne(db, 0, 0, 0); } if( sqlite3VtabEponymousTableInit(pParse, pMod) ){ return pMod->pEpoTab; } } } #endif if( flags & LOCATE_NOERR ) return 0; |
> > > > > > > > > > > > > > > > | < < < < < < < | < < | < < < < < |
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 ... 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 ... 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 |
** 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 ................................................................................ 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); } } } ................................................................................ ** 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 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 ){ sqlite3SchemaDisconnect(db, iDb, 1); }else{ sqlite3SchemaClear(pDb->pSchema); } } /* |
| |
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
...
329
330
331
332
333
334
335
336
337
338
339
340
341
342
|
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;
................................................................................
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);
}
|
>
>
>
|
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
...
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
|
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; ................................................................................ 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 70 71 72 |
SELECT * FROM t2
} {1 4}
do_execsql_test 1.9 {
SELECT * FROM v1
} {1 2 3 4 5 6}
finish_test
|
< > > > > > > > > > | > > > > > > > > > > > > |
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 |