mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.43 2000/01/26 05:56:43 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.44 2000/03/17 05:29:05 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "parser/analyze.h"
|
||||
#include "parser/gramparse.h"
|
||||
#include "parser/parser.h"
|
||||
#include "parser/parse_expr.h"
|
||||
|
||||
#if defined(FLEX_SCANNER)
|
||||
extern void DeleteBuffer(void);
|
||||
@@ -46,6 +47,8 @@ parser(char *str, Oid *typev, int nargs)
|
||||
parsetree = NIL; /* in case parser forgets to set it */
|
||||
|
||||
parser_init(typev, nargs);
|
||||
parse_expr_init();
|
||||
|
||||
yyresult = yyparse();
|
||||
|
||||
#if defined(FLEX_SCANNER)
|
||||
|
||||
Reference in New Issue
Block a user