diff options
-rw-r--r-- | Tests/LibSQL/TestSqlExpressionParser.cpp | 7 | ||||
-rw-r--r-- | Userland/Libraries/LibSQL/Parser.cpp | 6 | ||||
-rw-r--r-- | Userland/Libraries/LibSQL/Parser.h | 6 |
3 files changed, 19 insertions, 0 deletions
diff --git a/Tests/LibSQL/TestSqlExpressionParser.cpp b/Tests/LibSQL/TestSqlExpressionParser.cpp index c2a6b3bfd7..4cf58324f2 100644 --- a/Tests/LibSQL/TestSqlExpressionParser.cpp +++ b/Tests/LibSQL/TestSqlExpressionParser.cpp @@ -602,3 +602,10 @@ TEST_CASE(in_selection_expression) validate("15 IN (SELECT * FROM table)", false); validate("15 NOT IN (SELECT * FROM table)", true); } + +TEST_CASE(stack_limit) +{ + auto too_deep_expression = String::formatted("{:+^{}}1", "", SQL::Limits::maximum_expression_tree_depth); + EXPECT(!parse(too_deep_expression.substring_view(1)).is_error()); + EXPECT(parse(too_deep_expression).is_error()); +} diff --git a/Userland/Libraries/LibSQL/Parser.cpp b/Userland/Libraries/LibSQL/Parser.cpp index 26d3fac53f..d3de815094 100644 --- a/Userland/Libraries/LibSQL/Parser.cpp +++ b/Userland/Libraries/LibSQL/Parser.cpp @@ -352,6 +352,11 @@ RefPtr<CommonTableExpressionList> Parser::parse_common_table_expression_list() NonnullRefPtr<Expression> Parser::parse_expression() { + if (++m_parser_state.m_current_expression_depth > Limits::maximum_expression_tree_depth) { + syntax_error(String::formatted("Exceeded maximum expression tree depth of {}", Limits::maximum_expression_tree_depth)); + return create_ast_node<ErrorExpression>(); + } + // https://sqlite.org/lang_expr.html auto expression = parse_primary_expression(); @@ -362,6 +367,7 @@ NonnullRefPtr<Expression> Parser::parse_expression() // FIXME: Parse 'function-name'. // FIXME: Parse 'raise-function'. + --m_parser_state.m_current_expression_depth; return expression; } diff --git a/Userland/Libraries/LibSQL/Parser.h b/Userland/Libraries/LibSQL/Parser.h index 74595a3b7e..e9f202514d 100644 --- a/Userland/Libraries/LibSQL/Parser.h +++ b/Userland/Libraries/LibSQL/Parser.h @@ -14,6 +14,11 @@ namespace SQL { +namespace Limits { +// https://www.sqlite.org/limits.html +constexpr size_t maximum_expression_tree_depth = 1000; +} + class Parser { struct Position { size_t line { 0 }; @@ -48,6 +53,7 @@ private: Lexer m_lexer; Token m_token; Vector<Error> m_errors; + size_t m_current_expression_depth { 0 }; }; NonnullRefPtr<Statement> parse_statement(); |