diff --git a/manifest b/manifest index 84db379558..256136651f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sthe\ssignatures\sof\sthe\ssqlite3_vfs.xAccess\sand\ssqlite3_vfs.xCheckReservedLock\sfunctions.\s(CVS\s5188) -D 2008-06-05T11:39:11 +C Reorganize\ssome\sof\sthe\scode\sthat\sdetects\sexpression\strees\swith\sa\sdepth\sgreater\sthan\sEXPR_MAX_DEPTH\sso\sthat\sthey\sare\sdetected\searlier.\sThis\sfurther\sreduces\sthe\sopportunities\sfor\sstack\soverflow.\s(CVS\s5189) +D 2008-06-05T16:47:39 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in ce92ea8dc7adfb743757794f51c10d1b0d9c55e4 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -104,7 +104,7 @@ F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0 F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131 F src/date.c b305ced9f4da66b51ef020d9bf31c6c92fc0c6bb F src/delete.c d3fc5987f2eb88f7b9549d58a5dfea079a83fe8b -F src/expr.c 52fbb644cf5e9b70329e95c67552e74c3cba81b7 +F src/expr.c ecb3b23d3543427cba3e2ac12a6c6ae4bb20d39b F src/fault.c 1f6177188edb00641673e462f3fab8cba9f7422b F src/func.c 77a910a1ca7613d291fd0b5cba3be14c02f0dce0 F src/hash.c fd8cb06fb54c2fe7d48c9195792059a2e5be8b70 @@ -135,7 +135,7 @@ F src/os_unix.c bea384cc48cc03630703fbf3afbc9ee4b5442663 F src/os_win.c 9ac4e4e9c864b16e5dd087eed5770c960a5b1f09 F src/pager.c 912792937cba5838c4515a7a284c9f57f56d603e F src/pager.h 71c58cd613174a91b50ed66edad6148639aa064a -F src/parse.y fc4bd35c6088901f7c8daead26c6fb11c87d22e7 +F src/parse.y 8c2c3145eebe1964eb279cb3c4e502eae28bb0fa F src/pragma.c 70e7c865dce85fdf9df81848af2169009a56ed08 F src/prepare.c cbc9301aba1d0fc3d05fae576f2eb667c189cb36 F src/printf.c f2d4f6c5b0ec24b643e85fe60258adad8b1f6acc @@ -144,7 +144,7 @@ F src/select.c da43ce3080112aa77863e9c570c1df19a892acb8 F src/shell.c a12ea645271b7876c8f080146f48e20b00d367ec F src/sqlite.h.in 0f4f33b54824cc8077c028a85a1dbd8a3df4fa73 F src/sqlite3ext.h faacd0e6a81aabee0861c6d7883c9172e74ef5b3 -F src/sqliteInt.h cfcb83222431108aa51565efecf3a084360ad4a6 +F src/sqliteInt.h debc576f4476cde358f3c7d8214b0c2f47b24555 F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8 F src/table.c 1fa8f8113ac9cbc09ae4801c6d2a7f0af82c5822 F src/tclsqlite.c c57e740e30bd6dda678796eed62c7f0e64689834 @@ -591,7 +591,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1 F tool/speedtest8inst1.c c65494ca99d1e09c246dfe37a7ca7a354af9990f -P 9ab87b7b0d0195787f1527b5be1475fb89330f08 -R f736eee5959ea7b2b1c25bb8c6d7f381 +P 4226ac54beea1b58de8ab7b9d768d999f50438a6 +R 15114df36c8c1f1e10e6cc53ddf8867c U danielk1977 -Z 8a3aacae4ecc1da5df29c6db6f201b0d +Z b0654222f29652b857476f2b1403ea27 diff --git a/manifest.uuid b/manifest.uuid index 1fd87c167c..e257adf45e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4226ac54beea1b58de8ab7b9d768d999f50438a6 \ No newline at end of file +16d4c53a8e4d3cfc1abac3b8bb44d8bfd9471e32 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 5813e2d2c0..298dbac0cf 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.372 2008/05/28 13:49:36 drh Exp $ +** $Id: expr.c,v 1.373 2008/06/05 16:47:39 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -253,6 +253,101 @@ static int codeCompare( return addr; } +#if SQLITE_MAX_EXPR_DEPTH>0 +/* +** Check that argument nHeight is less than or equal to the maximum +** expression depth allowed. If it is not, leave an error message in +** pParse. +*/ +static int checkExprHeight(Parse *pParse, int nHeight){ + int rc = SQLITE_OK; + int mxHeight = pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH]; + if( nHeight>mxHeight ){ + sqlite3ErrorMsg(pParse, + "Expression tree is too large (maximum depth %d)", mxHeight + ); + rc = SQLITE_ERROR; + } + return rc; +} + +/* The following three functions, heightOfExpr(), heightOfExprList() +** and heightOfSelect(), are used to determine the maximum height +** of any expression tree referenced by the structure passed as the +** first argument. +** +** If this maximum height is greater than the current value pointed +** to by pnHeight, the second parameter, then set *pnHeight to that +** value. +*/ +static void heightOfExpr(Expr *p, int *pnHeight){ + if( p ){ + if( p->nHeight>*pnHeight ){ + *pnHeight = p->nHeight; + } + } +} +static void heightOfExprList(ExprList *p, int *pnHeight){ + if( p ){ + int i; + for(i=0; inExpr; i++){ + heightOfExpr(p->a[i].pExpr, pnHeight); + } + } +} +static void heightOfSelect(Select *p, int *pnHeight){ + if( p ){ + heightOfExpr(p->pWhere, pnHeight); + heightOfExpr(p->pHaving, pnHeight); + heightOfExpr(p->pLimit, pnHeight); + heightOfExpr(p->pOffset, pnHeight); + heightOfExprList(p->pEList, pnHeight); + heightOfExprList(p->pGroupBy, pnHeight); + heightOfExprList(p->pOrderBy, pnHeight); + heightOfSelect(p->pPrior, pnHeight); + } +} + +/* +** Set the Expr.nHeight variable in the structure passed as an +** argument. An expression with no children, Expr.pList or +** Expr.pSelect member has a height of 1. Any other expression +** has a height equal to the maximum height of any other +** referenced Expr plus one. +*/ +static void exprSetHeight(Expr *p){ + int nHeight = 0; + heightOfExpr(p->pLeft, &nHeight); + heightOfExpr(p->pRight, &nHeight); + heightOfExprList(p->pList, &nHeight); + heightOfSelect(p->pSelect, &nHeight); + p->nHeight = nHeight + 1; +} + +/* +** Set the Expr.nHeight variable using the exprSetHeight() function. If +** the height is greater than the maximum allowed expression depth, +** leave an error in pParse. +*/ +void sqlite3ExprSetHeight(Parse *pParse, Expr *p){ + exprSetHeight(p); + checkExprHeight(pParse, p->nHeight); +} + +/* +** Return the maximum height of any expression tree referenced +** by the select statement passed as an argument. +*/ +int sqlite3SelectExprHeight(Select *p){ + int nHeight = 0; + heightOfSelect(p, &nHeight); + return nHeight; +} +#else + #define checkExprHeight(x,y) + #define exprSetHeight(y) +#endif /* SQLITE_MAX_EXPR_DEPTH>0 */ + /* ** Construct a new expression node and return a pointer to it. Memory ** for this node is obtained from sqlite3_malloc(). The calling function @@ -297,7 +392,7 @@ Expr *sqlite3Expr( } } - sqlite3ExprSetHeight(pNew); + exprSetHeight(pNew); return pNew; } @@ -312,7 +407,11 @@ Expr *sqlite3PExpr( Expr *pRight, /* Right operand */ const Token *pToken /* Argument token */ ){ - return sqlite3Expr(pParse->db, op, pLeft, pRight, pToken); + Expr *p = sqlite3Expr(pParse->db, op, pLeft, pRight, pToken); + if( p ){ + checkExprHeight(pParse, p->nHeight); + } + return p; } /* @@ -391,7 +490,7 @@ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ pNew->token = *pToken; pNew->span = pNew->token; - sqlite3ExprSetHeight(pNew); + sqlite3ExprSetHeight(pParse, pNew); return pNew; } @@ -738,75 +837,6 @@ void sqlite3ExprListCheckLength( } } -/* The following three functions, heightOfExpr(), heightOfExprList() -** and heightOfSelect(), are used to determine the maximum height -** of any expression tree referenced by the structure passed as the -** first argument. -** -** If this maximum height is greater than the current value pointed -** to by pnHeight, the second parameter, then set *pnHeight to that -** value. -*/ -#if SQLITE_MAX_EXPR_DEPTH>0 -static void heightOfExpr(Expr *p, int *pnHeight){ - if( p ){ - if( p->nHeight>*pnHeight ){ - *pnHeight = p->nHeight; - } - } -} -static void heightOfExprList(ExprList *p, int *pnHeight){ - if( p ){ - int i; - for(i=0; inExpr; i++){ - heightOfExpr(p->a[i].pExpr, pnHeight); - } - } -} -static void heightOfSelect(Select *p, int *pnHeight){ - if( p ){ - heightOfExpr(p->pWhere, pnHeight); - heightOfExpr(p->pHaving, pnHeight); - heightOfExpr(p->pLimit, pnHeight); - heightOfExpr(p->pOffset, pnHeight); - heightOfExprList(p->pEList, pnHeight); - heightOfExprList(p->pGroupBy, pnHeight); - heightOfExprList(p->pOrderBy, pnHeight); - heightOfSelect(p->pPrior, pnHeight); - } -} -#endif /* SQLITE_MAX_EXPR_DEPTH>0 */ - -/* -** Set the Expr.nHeight variable in the structure passed as an -** argument. An expression with no children, Expr.pList or -** Expr.pSelect member has a height of 1. Any other expression -** has a height equal to the maximum height of any other -** referenced Expr plus one. -*/ -#if SQLITE_MAX_EXPR_DEPTH>0 -void sqlite3ExprSetHeight(Expr *p){ - int nHeight = 0; - heightOfExpr(p->pLeft, &nHeight); - heightOfExpr(p->pRight, &nHeight); - heightOfExprList(p->pList, &nHeight); - heightOfSelect(p->pSelect, &nHeight); - p->nHeight = nHeight + 1; -} -#endif /* SQLITE_MAX_EXPR_DEPTH>0 */ - -/* -** Return the maximum height of any expression tree referenced -** by the select statement passed as an argument. -*/ -#if SQLITE_MAX_EXPR_DEPTH>0 -int sqlite3SelectExprHeight(Select *p){ - int nHeight = 0; - heightOfSelect(p, &nHeight); - return nHeight; -} -#endif /* SQLITE_MAX_EXPR_DEPTH>0 */ - /* ** Delete an entire expression list. */ @@ -1536,11 +1566,7 @@ int sqlite3ExprResolveNames( if( pExpr==0 ) return 0; #if SQLITE_MAX_EXPR_DEPTH>0 { - int mxDepth = pNC->pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH]; - if( (pExpr->nHeight+pNC->pParse->nHeight)>mxDepth ){ - sqlite3ErrorMsg(pNC->pParse, - "Expression tree is too large (maximum depth %d)", mxDepth - ); + if( checkExprHeight(pNC->pParse, pExpr->nHeight + pNC->pParse->nHeight) ){ return 1; } pNC->pParse->nHeight += pExpr->nHeight; diff --git a/src/parse.y b/src/parse.y index 4df5db88eb..914cad15dc 100644 --- a/src/parse.y +++ b/src/parse.y @@ -14,7 +14,7 @@ ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** -** @(#) $Id: parse.y,v 1.243 2008/04/17 20:59:38 drh Exp $ +** @(#) $Id: parse.y,v 1.244 2008/06/05 16:47:39 danielk1977 Exp $ */ // All token codes are small integers with #defines that begin with "TK_" @@ -773,7 +773,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { A = sqlite3PExpr(pParse, TK_IN, X, 0, 0); if( A ){ A->pList = Y; - sqlite3ExprSetHeight(A); + sqlite3ExprSetHeight(pParse, A); }else{ sqlite3ExprListDelete(Y); } @@ -784,7 +784,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { A = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); if( A ){ A->pSelect = X; - sqlite3ExprSetHeight(A); + sqlite3ExprSetHeight(pParse, A); }else{ sqlite3SelectDelete(X); } @@ -794,7 +794,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { A = sqlite3PExpr(pParse, TK_IN, X, 0, 0); if( A ){ A->pSelect = Y; - sqlite3ExprSetHeight(A); + sqlite3ExprSetHeight(pParse, A); }else{ sqlite3SelectDelete(Y); } @@ -806,7 +806,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { A = sqlite3PExpr(pParse, TK_IN, X, 0, 0); if( A ){ A->pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); - sqlite3ExprSetHeight(A); + sqlite3ExprSetHeight(pParse, A); }else{ sqlite3SrcListDelete(pSrc); } @@ -818,7 +818,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { if( p ){ p->pSelect = Y; sqlite3ExprSpan(p,&B,&E); - sqlite3ExprSetHeight(A); + sqlite3ExprSetHeight(pParse, A); }else{ sqlite3SelectDelete(Y); } @@ -830,7 +830,7 @@ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). { A = sqlite3PExpr(pParse, TK_CASE, X, Z, 0); if( A ){ A->pList = Y; - sqlite3ExprSetHeight(A); + sqlite3ExprSetHeight(pParse, A); }else{ sqlite3ExprListDelete(Y); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index b00a8a5c1e..9981ef071c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.705 2008/05/28 13:49:36 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.706 2008/06/05 16:47:39 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -2196,10 +2196,10 @@ int sqlite3FindInIndex(Parse *, Expr *, int); #endif #if SQLITE_MAX_EXPR_DEPTH>0 - void sqlite3ExprSetHeight(Expr *); + void sqlite3ExprSetHeight(Parse *pParse, Expr *p); int sqlite3SelectExprHeight(Select *); #else - #define sqlite3ExprSetHeight(x) + #define sqlite3ExprSetHeight(x,y) #define sqlite3SelectExprHeight(x) 0 #endif