aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <dan@noemail.net>2009-09-22 15:53:47 +0000
committerdan <dan@noemail.net>2009-09-22 15:53:47 +0000
commit29c7f9caace234a30587b41c1ff009e425edab71 (patch)
treea9f94e930529a557ff54f21c55fb1e05da1f1273 /src
parent3e82c1d99b5720fb2daec15b8ad872f4be44877e (diff)
downloadsqlite-29c7f9caace234a30587b41c1ff009e425edab71.tar.gz
sqlite-29c7f9caace234a30587b41c1ff009e425edab71.zip
Fix an OOM related crash in fkey.c.
FossilOrigin-Name: 635d6a775a3f192d4292738905f5e01bc956a712
Diffstat (limited to 'src')
-rw-r--r--src/fkey.c81
1 files changed, 47 insertions, 34 deletions
diff --git a/src/fkey.c b/src/fkey.c
index 072a90aee..77babe54c 100644
--- a/src/fkey.c
+++ b/src/fkey.c
@@ -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;