浏览代码

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.
Timothy Flynn 4 年之前
父节点
当前提交
c7cd81bce8
共有 3 个文件被更改,包括 15 次插入0 次删除
  1. 7 0
      Tests/LibSQL/TestSqlStatementParser.cpp
  2. 6 0
      Userland/Libraries/LibSQL/Parser.cpp
  3. 2 0
      Userland/Libraries/LibSQL/Parser.h

+ 7 - 0
Tests/LibSQL/TestSqlStatementParser.cpp

@@ -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());
+}

+ 6 - 0
Userland/Libraries/LibSQL/Parser.cpp

@@ -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;

+ 2 - 0
Userland/Libraries/LibSQL/Parser.h

@@ -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();