From c80aeb0ef1b04fda55b4613ac4fc270a82f59e41 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 10 Aug 2019 20:08:14 +0300 Subject: [PATCH] Fixed another case; added a test --- dbms/src/Parsers/ExpressionListParsers.cpp | 5 +++++ .../0_stateless/00984_parser_stack_overflow.reference | 2 ++ .../tests/queries/0_stateless/00984_parser_stack_overflow.sh | 2 ++ 3 files changed, 9 insertions(+) diff --git a/dbms/src/Parsers/ExpressionListParsers.cpp b/dbms/src/Parsers/ExpressionListParsers.cpp index 4c8ef64b80..6f2e3f103c 100644 --- a/dbms/src/Parsers/ExpressionListParsers.cpp +++ b/dbms/src/Parsers/ExpressionListParsers.cpp @@ -139,6 +139,7 @@ bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, ASTPtr & node { bool first = true; + auto current_depth = pos.depth; while (1) { if (first) @@ -190,10 +191,14 @@ bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, ASTPtr & node ++pos; } + /// Left associative operator chain is parsed as a tree: ((((1 + 1) + 1) + 1) + 1)... + /// We must account it's depth - otherwise we may end up with stack overflow later - on destruction of AST. + pos.increaseDepth(); node = function; } } + pos.depth = current_depth; return true; } diff --git a/dbms/tests/queries/0_stateless/00984_parser_stack_overflow.reference b/dbms/tests/queries/0_stateless/00984_parser_stack_overflow.reference index 50d27ab5d8..a46c80e923 100644 --- a/dbms/tests/queries/0_stateless/00984_parser_stack_overflow.reference +++ b/dbms/tests/queries/0_stateless/00984_parser_stack_overflow.reference @@ -1,4 +1,6 @@ exceeded exceeded exceeded +exceeded 20002 +1 diff --git a/dbms/tests/queries/0_stateless/00984_parser_stack_overflow.sh b/dbms/tests/queries/0_stateless/00984_parser_stack_overflow.sh index cfb08d30cd..64fae3fb0f 100755 --- a/dbms/tests/queries/0_stateless/00984_parser_stack_overflow.sh +++ b/dbms/tests/queries/0_stateless/00984_parser_stack_overflow.sh @@ -7,6 +7,8 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) perl -e 'print "(" x 10000' | $CLICKHOUSE_CURL -sS "$CLICKHOUSE_URL" --data-binary @- | grep -oF 'exceeded' perl -e 'print "SELECT " . ("[" x 10000)' | $CLICKHOUSE_CURL -sS "$CLICKHOUSE_URL" --data-binary @- | grep -oF 'exceeded' perl -e 'print "SELECT " . ("([" x 5000)' | $CLICKHOUSE_CURL -sS "$CLICKHOUSE_URL" --data-binary @- | grep -oF 'exceeded' +perl -e 'print "SELECT 1" . ("+1" x 10000)' | $CLICKHOUSE_CURL -sS "$CLICKHOUSE_URL" --data-binary @- | grep -oF 'exceeded' # But this is Ok perl -e 'print "SELECT 1" . (",1" x 10000)' | $CLICKHOUSE_CURL -sS "$CLICKHOUSE_URL" --data-binary @- | wc -c +perl -e 'print "SELECT 1" . (" OR 1" x 10000)' | $CLICKHOUSE_CURL -sS "$CLICKHOUSE_URL" --data-binary @- -- GitLab