aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_expr.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-03-17 05:29:07 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-03-17 05:29:07 +0000
commit0e314d747e2803a9bea7ee69ab0c7df881277eba (patch)
tree45ea45c0dba5c1b2e950d156949be0d8d841746d /src/backend/parser/parse_expr.c
parent341b328b180e65d1fa5c8f2235cf101c8a12824f (diff)
downloadpostgresql-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.c34
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;
}