mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Make sure all memory from sqlite3DbMalloc() is freed by sqlite3DbFree() and
all memory from sqlite3_malloc() is freed by sqlite3_free(). FossilOrigin-Name: ac1f37a647e9ed1c00a901d26d9956a86c40117a
This commit is contained in:
48
src/vdbe.c
48
src/vdbe.c
@@ -501,6 +501,20 @@ static int checkSavepointCount(sqlite3 *db){
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored
|
||||
** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored
|
||||
** in memory obtained from sqlite3DbMalloc).
|
||||
*/
|
||||
static void importVtabErrMsg(Vdbe *p, sqlite3_vtab *pVtab){
|
||||
sqlite3 *db = p->db;
|
||||
sqlite3DbFree(db, p->zErrMsg);
|
||||
p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
|
||||
sqlite3_free(pVtab->zErrMsg);
|
||||
pVtab->zErrMsg = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Execute as much of a VDBE program as we can then return.
|
||||
**
|
||||
@@ -4030,9 +4044,7 @@ case OP_Rowid: { /* out2-prerelease */
|
||||
pModule = pVtab->pModule;
|
||||
assert( pModule->xRowid );
|
||||
rc = pModule->xRowid(pC->pVtabCursor, &v);
|
||||
sqlite3DbFree(db, p->zErrMsg);
|
||||
p->zErrMsg = pVtab->zErrMsg;
|
||||
pVtab->zErrMsg = 0;
|
||||
importVtabErrMsg(p, pVtab);
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
}else{
|
||||
assert( pC->pCursor!=0 );
|
||||
@@ -5375,11 +5387,7 @@ case OP_VBegin: {
|
||||
VTable *pVTab;
|
||||
pVTab = pOp->p4.pVtab;
|
||||
rc = sqlite3VtabBegin(db, pVTab);
|
||||
if( pVTab ){
|
||||
sqlite3DbFree(db, p->zErrMsg);
|
||||
p->zErrMsg = pVTab->pVtab->zErrMsg;
|
||||
pVTab->pVtab->zErrMsg = 0;
|
||||
}
|
||||
if( pVTab ) importVtabErrMsg(p, pVTab->pVtab);
|
||||
break;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
@@ -5429,9 +5437,7 @@ case OP_VOpen: {
|
||||
pModule = (sqlite3_module *)pVtab->pModule;
|
||||
assert(pVtab && pModule);
|
||||
rc = pModule->xOpen(pVtab, &pVtabCursor);
|
||||
sqlite3DbFree(db, p->zErrMsg);
|
||||
p->zErrMsg = pVtab->zErrMsg;
|
||||
pVtab->zErrMsg = 0;
|
||||
importVtabErrMsg(p, pVtab);
|
||||
if( SQLITE_OK==rc ){
|
||||
/* Initialize sqlite3_vtab_cursor base class */
|
||||
pVtabCursor->pVtab = pVtab;
|
||||
@@ -5508,9 +5514,7 @@ case OP_VFilter: { /* jump */
|
||||
p->inVtabMethod = 1;
|
||||
rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
|
||||
p->inVtabMethod = 0;
|
||||
sqlite3DbFree(db, p->zErrMsg);
|
||||
p->zErrMsg = pVtab->zErrMsg;
|
||||
pVtab->zErrMsg = 0;
|
||||
importVtabErrMsg(p, pVtab);
|
||||
if( rc==SQLITE_OK ){
|
||||
res = pModule->xEof(pVtabCursor);
|
||||
}
|
||||
@@ -5560,9 +5564,7 @@ case OP_VColumn: {
|
||||
MemSetTypeFlag(&sContext.s, MEM_Null);
|
||||
|
||||
rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
|
||||
sqlite3DbFree(db, p->zErrMsg);
|
||||
p->zErrMsg = pVtab->zErrMsg;
|
||||
pVtab->zErrMsg = 0;
|
||||
importVtabErrMsg(p, pVtab);
|
||||
if( sContext.isError ){
|
||||
rc = sContext.isError;
|
||||
}
|
||||
@@ -5615,9 +5617,7 @@ case OP_VNext: { /* jump */
|
||||
p->inVtabMethod = 1;
|
||||
rc = pModule->xNext(pCur->pVtabCursor);
|
||||
p->inVtabMethod = 0;
|
||||
sqlite3DbFree(db, p->zErrMsg);
|
||||
p->zErrMsg = pVtab->zErrMsg;
|
||||
pVtab->zErrMsg = 0;
|
||||
importVtabErrMsg(p, pVtab);
|
||||
if( rc==SQLITE_OK ){
|
||||
res = pModule->xEof(pCur->pVtabCursor);
|
||||
}
|
||||
@@ -5647,9 +5647,7 @@ case OP_VRename: {
|
||||
REGISTER_TRACE(pOp->p1, pName);
|
||||
assert( pName->flags & MEM_Str );
|
||||
rc = pVtab->pModule->xRename(pVtab, pName->z);
|
||||
sqlite3DbFree(db, p->zErrMsg);
|
||||
p->zErrMsg = pVtab->zErrMsg;
|
||||
pVtab->zErrMsg = 0;
|
||||
importVtabErrMsg(p, pVtab);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -5701,9 +5699,7 @@ case OP_VUpdate: {
|
||||
pX++;
|
||||
}
|
||||
rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
|
||||
sqlite3DbFree(db, p->zErrMsg);
|
||||
p->zErrMsg = pVtab->zErrMsg;
|
||||
pVtab->zErrMsg = 0;
|
||||
importVtabErrMsg(p, pVtab);
|
||||
if( rc==SQLITE_OK && pOp->p1 ){
|
||||
assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
|
||||
db->lastRowid = rowid;
|
||||
|
Reference in New Issue
Block a user