mirror of
https://github.com/RGBCube/serenity
synced 2025-05-20 16:55:08 +00:00
LibSQL: Limit the allowed depth of an expression tree
According to the definition at https://sqlite.org/lang_expr.html, SQL expressions could be infinitely deep. For practicality, SQLite enforces a maxiumum expression tree depth of 1000. Apply the same limit in LibSQL to avoid stack overflow in the expression parser. Fixes https://crbug.com/oss-fuzz/34859.
This commit is contained in:
parent
3d9bcb860e
commit
f8f36effc9
3 changed files with 19 additions and 0 deletions
|
@ -602,3 +602,10 @@ TEST_CASE(in_selection_expression)
|
||||||
validate("15 IN (SELECT * FROM table)", false);
|
validate("15 IN (SELECT * FROM table)", false);
|
||||||
validate("15 NOT IN (SELECT * FROM table)", true);
|
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());
|
||||||
|
}
|
||||||
|
|
|
@ -352,6 +352,11 @@ RefPtr<CommonTableExpressionList> Parser::parse_common_table_expression_list()
|
||||||
|
|
||||||
NonnullRefPtr<Expression> Parser::parse_expression()
|
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
|
// https://sqlite.org/lang_expr.html
|
||||||
auto expression = parse_primary_expression();
|
auto expression = parse_primary_expression();
|
||||||
|
|
||||||
|
@ -362,6 +367,7 @@ NonnullRefPtr<Expression> Parser::parse_expression()
|
||||||
// FIXME: Parse 'function-name'.
|
// FIXME: Parse 'function-name'.
|
||||||
// FIXME: Parse 'raise-function'.
|
// FIXME: Parse 'raise-function'.
|
||||||
|
|
||||||
|
--m_parser_state.m_current_expression_depth;
|
||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,11 @@
|
||||||
|
|
||||||
namespace SQL {
|
namespace SQL {
|
||||||
|
|
||||||
|
namespace Limits {
|
||||||
|
// https://www.sqlite.org/limits.html
|
||||||
|
constexpr size_t maximum_expression_tree_depth = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
class Parser {
|
class Parser {
|
||||||
struct Position {
|
struct Position {
|
||||||
size_t line { 0 };
|
size_t line { 0 };
|
||||||
|
@ -48,6 +53,7 @@ private:
|
||||||
Lexer m_lexer;
|
Lexer m_lexer;
|
||||||
Token m_token;
|
Token m_token;
|
||||||
Vector<Error> m_errors;
|
Vector<Error> m_errors;
|
||||||
|
size_t m_current_expression_depth { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
NonnullRefPtr<Statement> parse_statement();
|
NonnullRefPtr<Statement> parse_statement();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue