diff options
author | drh <drh@noemail.net> | 2006-07-11 13:15:08 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2006-07-11 13:15:08 +0000 |
commit | 206f3d96d140c9480f19bf92e8f7f35132048d4b (patch) | |
tree | b5e49af529118b78d55a415f27edbee35c6c0cc2 /src | |
parent | 76f8079623ba1e5b21dd4942fc6d53768abd96c1 (diff) | |
download | sqlite-206f3d96d140c9480f19bf92e8f7f35132048d4b.tar.gz sqlite-206f3d96d140c9480f19bf92e8f7f35132048d4b.zip |
Prevent memory leak and possible NULL pointer deference after malloc
failure. Ticket #1886. (CVS 3329)
FossilOrigin-Name: b1f326e6959ef3be11f772e80f5ab6dd65b2d065
Diffstat (limited to 'src')
-rw-r--r-- | src/expr.c | 15 | ||||
-rw-r--r-- | src/select.c | 20 | ||||
-rw-r--r-- | src/sqliteInt.h | 3 |
3 files changed, 29 insertions, 9 deletions
diff --git a/src/expr.c b/src/expr.c index 5ba7cde7c..4e8d322b9 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.265 2006/07/08 18:41:37 drh Exp $ +** $Id: expr.c,v 1.266 2006/07/11 13:15:08 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -212,6 +212,19 @@ Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){ } /* +** Works like sqlite3Expr() but frees its pLeft and pRight arguments +** if it fails due to a malloc problem. +*/ +Expr *sqlite3ExprOrFree(int op, Expr *pLeft, Expr *pRight, const Token *pToken){ + Expr *pNew = sqlite3Expr(op, pLeft, pRight, pToken); + if( pNew==0 ){ + sqlite3ExprDelete(pLeft); + sqlite3ExprDelete(pRight); + } + return pNew; +} + +/* ** When doing a nested parse, you can include terms in an expression ** that look like this: #0 #1 #2 ... These terms refer to elements ** on the stack. "#0" means the top of the stack. diff --git a/src/select.c b/src/select.c index c909fc00f..b6bb1f908 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.318 2006/06/21 07:02:33 danielk1977 Exp $ +** $Id: select.c,v 1.319 2006/07/11 13:15:08 drh Exp $ */ #include "sqliteInt.h" @@ -221,12 +221,17 @@ static void addWhereTerm( zAlias2 = pTab2->zName; } pE2b = sqlite3CreateIdExpr(zAlias2); - pE1c = sqlite3Expr(TK_DOT, pE1b, pE1a, 0); - pE2c = sqlite3Expr(TK_DOT, pE2b, pE2a, 0); - pE = sqlite3Expr(TK_EQ, pE1c, pE2c, 0); - ExprSetProperty(pE, EP_FromJoin); - pE->iRightJoinTable = iRightJoinTable; - *ppExpr = sqlite3ExprAnd(*ppExpr, pE); + pE1c = sqlite3ExprOrFree(TK_DOT, pE1b, pE1a, 0); + pE2c = sqlite3ExprOrFree(TK_DOT, pE2b, pE2a, 0); + pE = sqlite3ExprOrFree(TK_EQ, pE1c, pE2c, 0); + if( pE ){ + ExprSetProperty(pE, EP_FromJoin); + pE->iRightJoinTable = iRightJoinTable; + } + pE = sqlite3ExprAnd(*ppExpr, pE); + if( pE ){ + *ppExpr = pE; + } } /* @@ -2373,6 +2378,7 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){ pIdx = 0; }else{ CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr); + if( pColl==0 ) return 0; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ assert( pIdx->nColumn>=1 ); if( pIdx->aiColumn[0]==iCol && diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ff5edb0ec..360c69cdc 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.519 2006/07/08 18:35:00 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.520 2006/07/11 13:15:08 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1568,6 +1568,7 @@ int sqlite3KeywordCode(const unsigned char*, int); int sqlite3RunParser(Parse*, const char*, char **); void sqlite3FinishCoding(Parse*); Expr *sqlite3Expr(int, Expr*, Expr*, const Token*); +Expr *sqlite3ExprOrFree(int, Expr*, Expr*, const Token*); Expr *sqlite3RegisterExpr(Parse*,Token*); Expr *sqlite3ExprAnd(Expr*, Expr*); void sqlite3ExprSpan(Expr*,Token*,Token*); |