diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2000-03-17 05:29:07 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2000-03-17 05:29:07 +0000 |
commit | 0e314d747e2803a9bea7ee69ab0c7df881277eba (patch) | |
tree | 45ea45c0dba5c1b2e950d156949be0d8d841746d /src/backend/parser/parse_expr.c | |
parent | 341b328b180e65d1fa5c8f2235cf101c8a12824f (diff) | |
download | postgresql-0e314d747e2803a9bea7ee69ab0c7df881277eba.tar.gz postgresql-0e314d747e2803a9bea7ee69ab0c7df881277eba.zip |
Add safety check on expression nesting depth. Default value is set by
a config.h #define, and the runtime value can be controlled via SET.
Diffstat (limited to 'src/backend/parser/parse_expr.c')
-rw-r--r-- | src/backend/parser/parse_expr.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index e2e297cb6b6..419ad4d6d29 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.73 2000/03/14 23:06:32 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.74 2000/03/17 05:29:05 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -32,6 +32,11 @@ #include "utils/builtins.h" #include "utils/syscache.h" + +int max_expr_depth = DEFAULT_MAX_EXPR_DEPTH; + +static int expr_depth_counter = 0; + static Node *parser_typecast_constant(Value *expr, TypeName *typename); static Node *parser_typecast_expression(ParseState *pstate, Node *expr, TypeName *typename); @@ -40,6 +45,20 @@ static Node *transformIdent(ParseState *pstate, Ident *ident, int precedence); static Node *transformIndirection(ParseState *pstate, Node *basenode, List *indirection); + +/* + * Initialize for parsing a new query. + * + * We reset the expression depth counter here, in case it was left nonzero + * due to elog()'ing out of the last parsing operation. + */ +void +parse_expr_init(void) +{ + expr_depth_counter = 0; +} + + /* * transformExpr - * analyze and transform expressions. Type checking and type casting is @@ -55,6 +74,17 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) if (expr == NULL) return NULL; + /* + * Guard against an overly complex expression leading to coredump + * due to stack overflow here, or in later recursive routines that + * traverse expression trees. Note that this is very unlikely to + * happen except with pathological queries; but we don't want someone + * to be able to crash the backend quite that easily... + */ + if (++expr_depth_counter > max_expr_depth) + elog(ERROR, "Expression too complex: nesting depth exceeds max_expr_depth = %d", + max_expr_depth); + switch (nodeTag(expr)) { case T_Attr: @@ -532,6 +562,8 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) break; } + expr_depth_counter--; + return result; } |