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

Fix an OOM related crash in fkey.c.

FossilOrigin-Name: 635d6a775a3f192d4292738905f5e01bc956a712
This commit is contained in:
dan
2009-09-22 15:53:47 +00:00
parent 3e82c1d99b
commit 29c7f9caac
5 changed files with 123 additions and 43 deletions

View File

@@ -622,8 +622,8 @@ static Trigger *fkActionTrigger(
ExprList *pChanges /* Change-list for UPDATE, NULL for DELETE */
){
sqlite3 *db = pParse->db; /* Database handle */
int action;
Trigger *pTrigger;
int action; /* One of OE_None, OE_Cascade etc. */
Trigger *pTrigger; /* Trigger definition to return */
if( pChanges ){
action = pFKey->updateConf;
@@ -637,43 +637,26 @@ static Trigger *fkActionTrigger(
assert( OE_Cascade>OE_Restrict && OE_None<OE_Restrict );
if( action>OE_Restrict && !pTrigger ){
u8 enableLookaside; /* Copy of db->lookaside.bEnabled */
char const *zFrom; /* Name of referencing table */
int nFrom; /* Length in bytes of zFrom */
Index *pIdx = 0;
int *aiCol = 0;
TriggerStep *pStep;
sqlite3 *dbMem = pTab->dbMem;
Expr *pWhere = 0;
ExprList *pList = 0;
int i;
Index *pIdx = 0; /* Parent key index for this FK */
int *aiCol = 0; /* child table cols -> parent key cols */
TriggerStep *pStep; /* First (only) step of trigger program */
Expr *pWhere = 0; /* WHERE clause of trigger step */
ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */
int i; /* Iterator variable */
if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0;
assert( aiCol || pFKey->nCol==1 );
assert( dbMem==0 || dbMem==pParse->db );
zFrom = pFKey->pFrom->zName;
nFrom = sqlite3Strlen30(zFrom);
pTrigger = (Trigger *)sqlite3DbMallocZero(dbMem,
sizeof(Trigger) + /* struct Trigger */
sizeof(TriggerStep) + /* Single step in trigger program */
nFrom + 1 /* Space for pStep->target.z */
);
if( !pTrigger ){
pParse->db->mallocFailed = 1;
return 0;
}
pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
pStep->target.z = (char *)&pStep[1];
pStep->target.n = nFrom;
memcpy((char *)pStep->target.z, zFrom, nFrom);
for(i=0; i<pFKey->nCol; i++){
Expr *pEq;
int iFromCol; /* Idx of column in referencing table */
Token tFromCol; /* Name of column in referencing table */
Token tToCol; /* Name of column in referenced table */
Token tOld = { "old", 3 }; /* Literal "old" token */
Token tNew = { "new", 3 }; /* Literal "new" token */
Token tFromCol; /* Name of column in referencing table */
Token tToCol; /* Name of column in referenced table */
int iFromCol; /* Idx of column in referencing table */
Expr *pEq; /* tFromCol = OLD.tToCol */
iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
tToCol.z = pIdx ? pTab->aCol[pIdx->aiColumn[i]].zName : "oid";
@@ -690,7 +673,7 @@ static Trigger *fkActionTrigger(
sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
, 0)
, 0);
pWhere = sqlite3ExprAnd(pParse->db, pWhere, pEq);
pWhere = sqlite3ExprAnd(db, pWhere, pEq);
if( action!=OE_Cascade || pChanges ){
Expr *pNew;
@@ -713,12 +696,42 @@ static Trigger *fkActionTrigger(
sqlite3ExprListSetName(pParse, pList, &tFromCol, 0);
}
}
sqlite3DbFree(pParse->db, aiCol);
sqlite3DbFree(db, aiCol);
/* If pTab->dbMem==0, then the table may be part of a shared-schema.
** Disable the lookaside buffer before allocating space for the
** trigger definition in this case. */
enableLookaside = db->lookaside.bEnabled;
if( pTab->dbMem==0 ){
db->lookaside.bEnabled = 0;
}
zFrom = pFKey->pFrom->zName;
nFrom = sqlite3Strlen30(zFrom);
pTrigger = (Trigger *)sqlite3DbMallocZero(db,
sizeof(Trigger) + /* struct Trigger */
sizeof(TriggerStep) + /* Single step in trigger program */
nFrom + 1 /* Space for pStep->target.z */
);
if( pTrigger ){
pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
pStep->target.z = (char *)&pStep[1];
pStep->target.n = nFrom;
memcpy((char *)pStep->target.z, zFrom, nFrom);
pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
}
/* Re-enable the lookaside buffer, if it was disabled earlier. */
db->lookaside.bEnabled = enableLookaside;
pStep->pWhere = sqlite3ExprDup(dbMem, pWhere, EXPRDUP_REDUCE);
pStep->pExprList = sqlite3ExprListDup(dbMem, pList, EXPRDUP_REDUCE);
sqlite3ExprDelete(pParse->db, pWhere);
sqlite3ExprListDelete(pParse->db, pList);
if( db->mallocFailed==1 ){
fkTriggerDelete(db, pTrigger);
return 0;
}
pStep->op = (action!=OE_Cascade || pChanges) ? TK_UPDATE : TK_DELETE;
pStep->pTrig = pTrigger;