1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Fix a case where a malloc() error could lead to mismatched virtual-table xBegin/xCommit/xRollback callbacks.

FossilOrigin-Name: d807304a695fc85402b86e1cd32a6e3bbb2823c8
This commit is contained in:
dan
2011-05-25 18:46:22 +00:00
parent addd8f8729
commit 2cac2078f6
3 changed files with 30 additions and 16 deletions

View File

@@ -577,11 +577,11 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
return rc;
}
/*
** Add the virtual table pVTab to the array sqlite3.aVTrans[].
** Grow the db->aVTrans[] array so that there is room for at least one
** more v-table. Return SQLITE_NOMEM if a malloc fails, or SQLITE_OK otherwise.
*/
static int addToVTrans(sqlite3 *db, VTable *pVTab){
static int growVTrans(sqlite3 *db){
const int ARRAY_INCR = 5;
/* Grow the sqlite3.aVTrans array if required */
@@ -596,10 +596,17 @@ static int addToVTrans(sqlite3 *db, VTable *pVTab){
db->aVTrans = aVTrans;
}
return SQLITE_OK;
}
/*
** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should
** have already been reserved using growVTrans().
*/
static void addToVTrans(sqlite3 *db, VTable *pVTab){
/* Add pVtab to the end of sqlite3.aVTrans */
db->aVTrans[db->nVTrans++] = pVTab;
sqlite3VtabLock(pVTab);
return SQLITE_OK;
}
/*
@@ -637,7 +644,10 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
/* Justification of ALWAYS(): The xConstructor method is required to
** create a valid sqlite3_vtab if it returns SQLITE_OK. */
if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){
rc = addToVTrans(db, sqlite3GetVTable(db, pTab));
rc = growVTrans(db);
if( rc==SQLITE_OK ){
addToVTrans(db, sqlite3GetVTable(db, pTab));
}
}
return rc;
@@ -843,10 +853,14 @@ int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){
}
}
/* Invoke the xBegin method */
rc = pModule->xBegin(pVTab->pVtab);
/* Invoke the xBegin method. If successful, add the vtab to the
** sqlite3.aVTrans[] array. */
rc = growVTrans(db);
if( rc==SQLITE_OK ){
rc = addToVTrans(db, pVTab);
rc = pModule->xBegin(pVTab->pVtab);
if( rc==SQLITE_OK ){
addToVTrans(db, pVTab);
}
}
}
return rc;