Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Reorganize some of the code that detects expression trees with a depth greater than EXPR_MAX_DEPTH so that they are detected earlier. This further reduces the opportunities for stack overflow. (CVS 5189) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
16d4c53a8e4d3cfc1abac3b8bb44d8bf |
User & Date: | danielk1977 2008-06-05 16:47:39.000 |
Context
2008-06-06
| ||
11:11 | Remove the xGetTempname() method from the vfs structure. Temp files are now opened by passing a NULL pointer as the filename to xOpen(). (CVS 5190) (check-in: 5173b3e816 user: danielk1977 tags: trunk) | |
2008-06-05
| ||
16:47 | Reorganize some of the code that detects expression trees with a depth greater than EXPR_MAX_DEPTH so that they are detected earlier. This further reduces the opportunities for stack overflow. (CVS 5189) (check-in: 16d4c53a8e user: danielk1977 tags: trunk) | |
11:39 | Modify the signatures of the sqlite3_vfs.xAccess and sqlite3_vfs.xCheckReservedLock functions. (CVS 5188) (check-in: 4226ac54be user: danielk1977 tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.373 2008/06/05 16:47:39 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
249 250 251 252 253 254 255 256 257 258 259 260 261 262 | if( p5 & SQLITE_AFF_MASK ){ sqlite3ExprCacheAffinityChange(pParse, in1, 1); sqlite3ExprCacheAffinityChange(pParse, in2, 1); } return addr; } /* ** Construct a new expression node and return a pointer to it. Memory ** for this node is obtained from sqlite3_malloc(). The calling function ** is responsible for making sure the node eventually gets freed. */ Expr *sqlite3Expr( sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 | if( p5 & SQLITE_AFF_MASK ){ sqlite3ExprCacheAffinityChange(pParse, in1, 1); sqlite3ExprCacheAffinityChange(pParse, in2, 1); } 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; i<p->nExpr; 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 ** is responsible for making sure the node eventually gets freed. */ Expr *sqlite3Expr( sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */ |
︙ | ︙ | |||
293 294 295 296 297 298 299 | } if( pLeft->flags & EP_ExpCollate ){ pNew->flags |= EP_ExpCollate; pNew->pColl = pLeft->pColl; } } | | | > > > > | 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 | } if( pLeft->flags & EP_ExpCollate ){ pNew->flags |= EP_ExpCollate; pNew->pColl = pLeft->pColl; } } exprSetHeight(pNew); return pNew; } /* ** Works like sqlite3Expr() except that it takes an extra Parse* ** argument and notifies the associated connection object if malloc fails. */ Expr *sqlite3PExpr( Parse *pParse, /* Parsing context */ int op, /* Expression opcode */ Expr *pLeft, /* Left operand */ Expr *pRight, /* Right operand */ const Token *pToken /* Argument token */ ){ Expr *p = sqlite3Expr(pParse->db, op, pLeft, pRight, pToken); if( p ){ checkExprHeight(pParse, p->nHeight); } return p; } /* ** When doing a nested parse, you can include terms in an expression ** that look like this: #1 #2 ... These terms refer to registers ** in the virtual machine. #N is the N-th register. ** |
︙ | ︙ | |||
387 388 389 390 391 392 393 | } pNew->op = TK_FUNCTION; pNew->pList = pList; assert( pToken->dyn==0 ); pNew->token = *pToken; pNew->span = pNew->token; | | | 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 | } pNew->op = TK_FUNCTION; pNew->pList = pList; assert( pToken->dyn==0 ); pNew->token = *pToken; pNew->span = pNew->token; sqlite3ExprSetHeight(pParse, pNew); return pNew; } /* ** Assign a variable number to an expression that encodes a wildcard ** in the original SQL statement. ** |
︙ | ︙ | |||
734 735 736 737 738 739 740 | testcase( pEList && pEList->nExpr==mx ); testcase( pEList && pEList->nExpr==mx+1 ); if( pEList && pEList->nExpr>mx ){ sqlite3ErrorMsg(pParse, "too many columns in %s", zObject); } } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 833 834 835 836 837 838 839 840 841 842 843 844 845 846 | testcase( pEList && pEList->nExpr==mx ); testcase( pEList && pEList->nExpr==mx+1 ); if( pEList && pEList->nExpr>mx ){ sqlite3ErrorMsg(pParse, "too many columns in %s", zObject); } } /* ** Delete an entire expression list. */ void sqlite3ExprListDelete(ExprList *pList){ int i; struct ExprList_item *pItem; if( pList==0 ) return; |
︙ | ︙ | |||
1532 1533 1534 1535 1536 1537 1538 | Expr *pExpr /* The expression to be analyzed. */ ){ int savedHasAgg; if( pExpr==0 ) return 0; #if SQLITE_MAX_EXPR_DEPTH>0 { | < < | < < | 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 | Expr *pExpr /* The expression to be analyzed. */ ){ int savedHasAgg; if( pExpr==0 ) return 0; #if SQLITE_MAX_EXPR_DEPTH>0 { if( checkExprHeight(pNC->pParse, pExpr->nHeight + pNC->pParse->nHeight) ){ return 1; } pNC->pParse->nHeight += pExpr->nHeight; } #endif savedHasAgg = pNC->hasAgg; pNC->hasAgg = 0; |
︙ | ︙ |
Changes to src/parse.y.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** ** @(#) $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_" %token_prefix TK_ // The type of the data attached to each token is Token. This is also the // default type for non-terminals. |
︙ | ︙ | |||
769 770 771 772 773 774 775 | %type in_op {int} in_op(A) ::= IN. {A = 0;} in_op(A) ::= NOT IN. {A = 1;} expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] { A = sqlite3PExpr(pParse, TK_IN, X, 0, 0); if( A ){ A->pList = Y; | | | | | | | | 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 | %type in_op {int} in_op(A) ::= IN. {A = 0;} in_op(A) ::= NOT IN. {A = 1;} expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] { A = sqlite3PExpr(pParse, TK_IN, X, 0, 0); if( A ){ A->pList = Y; sqlite3ExprSetHeight(pParse, A); }else{ sqlite3ExprListDelete(Y); } if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0, 0); sqlite3ExprSpan(A,&X->span,&E); } expr(A) ::= LP(B) select(X) RP(E). { A = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); if( A ){ A->pSelect = X; sqlite3ExprSetHeight(pParse, A); }else{ sqlite3SelectDelete(X); } sqlite3ExprSpan(A,&B,&E); } expr(A) ::= expr(X) in_op(N) LP select(Y) RP(E). [IN] { A = sqlite3PExpr(pParse, TK_IN, X, 0, 0); if( A ){ A->pSelect = Y; sqlite3ExprSetHeight(pParse, A); }else{ sqlite3SelectDelete(Y); } if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0, 0); sqlite3ExprSpan(A,&X->span,&E); } expr(A) ::= expr(X) in_op(N) nm(Y) dbnm(Z). [IN] { SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z); A = sqlite3PExpr(pParse, TK_IN, X, 0, 0); if( A ){ A->pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); sqlite3ExprSetHeight(pParse, A); }else{ sqlite3SrcListDelete(pSrc); } if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0, 0); sqlite3ExprSpan(A,&X->span,Z.z?&Z:&Y); } expr(A) ::= EXISTS(B) LP select(Y) RP(E). { Expr *p = A = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); if( p ){ p->pSelect = Y; sqlite3ExprSpan(p,&B,&E); sqlite3ExprSetHeight(pParse, A); }else{ sqlite3SelectDelete(Y); } } %endif SQLITE_OMIT_SUBQUERY /* CASE expressions */ 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(pParse, A); }else{ sqlite3ExprListDelete(Y); } sqlite3ExprSpan(A, &C, &E); } %type case_exprlist {ExprList*} %destructor case_exprlist {sqlite3ExprListDelete($$);} |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.706 2008/06/05 16:47:39 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Include the configuration header output by 'configure' if we're using the ** autoconf-based build |
︙ | ︙ | |||
2192 2193 2194 2195 2196 2197 2198 | int sqlite3JournalSize(sqlite3_vfs *); int sqlite3JournalCreate(sqlite3_file *); #else #define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile) #endif #if SQLITE_MAX_EXPR_DEPTH>0 | | | | 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 | int sqlite3JournalSize(sqlite3_vfs *); int sqlite3JournalCreate(sqlite3_file *); #else #define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile) #endif #if SQLITE_MAX_EXPR_DEPTH>0 void sqlite3ExprSetHeight(Parse *pParse, Expr *p); int sqlite3SelectExprHeight(Select *); #else #define sqlite3ExprSetHeight(x,y) #define sqlite3SelectExprHeight(x) 0 #endif u32 sqlite3Get4byte(const u8*); void sqlite3Put4byte(u8*, u32); #ifdef SQLITE_SSE |
︙ | ︙ |