LibSQL: Limit the number of nested subqueries

SQLite hasn't documented a limit on https://www.sqlite.org/limits.html
for the maximum number of nested subqueries. However, its parser is
generated with Yacc and has an internal limit of 100 for general nested
statements.

Fixes https://crbug.com/oss-fuzz/35022.
This commit is contained in:
Timothy Flynn 2021-06-08 09:22:06 -04:00 committed by Andreas Kling
parent 4e974e6d60
commit c7cd81bce8
Notes: sideshowbarker 2024-07-18 12:37:11 +09:00
3 changed files with 15 additions and 0 deletions

View file

@ -738,3 +738,10 @@ TEST_CASE(common_table_expression)
validate("WITH table (column1, column2) AS (SELECT * FROM table) DELETE FROM table;", { false, { { "table", { "column1", "column2" } } } });
validate("WITH RECURSIVE table AS (SELECT * FROM table) DELETE FROM table;", { true, { { "table", {} } } });
}
TEST_CASE(nested_subquery_limit)
{
auto subquery = String::formatted("{:(^{}}table{:)^{}}", "", SQL::Limits::maximum_subquery_depth - 1, "", SQL::Limits::maximum_subquery_depth - 1);
EXPECT(!parse(String::formatted("SELECT * FROM {};", subquery)).is_error());
EXPECT(parse(String::formatted("SELECT * FROM ({});", subquery)).is_error());
}

View file

@ -5,6 +5,7 @@
*/
#include "Parser.h"
#include <AK/ScopeGuard.h>
#include <AK/TypeCasts.h>
namespace SQL {
@ -946,6 +947,11 @@ NonnullRefPtr<ResultColumn> Parser::parse_result_column()
NonnullRefPtr<TableOrSubquery> Parser::parse_table_or_subquery()
{
if (++m_parser_state.m_current_subquery_depth > Limits::maximum_subquery_depth)
syntax_error(String::formatted("Exceeded maximum subquery depth of {}", Limits::maximum_subquery_depth));
ScopeGuard guard([&]() { --m_parser_state.m_current_subquery_depth; });
// https://sqlite.org/syntax/table-or-subquery.html
if (match(TokenType::Identifier)) {
String schema_name;

View file

@ -17,6 +17,7 @@ namespace SQL {
namespace Limits {
// https://www.sqlite.org/limits.html
constexpr size_t maximum_expression_tree_depth = 1000;
constexpr size_t maximum_subquery_depth = 100;
}
class Parser {
@ -54,6 +55,7 @@ private:
Token m_token;
Vector<Error> m_errors;
size_t m_current_expression_depth { 0 };
size_t m_current_subquery_depth { 0 };
};
NonnullRefPtr<Statement> parse_statement();