From 3d2e53f49c28d5d8e6902a6430d8ac55955e073a Mon Sep 17 00:00:00 2001 From: Emil Ejbyfeldt Date: Wed, 4 Sep 2024 19:55:53 +0200 Subject: [PATCH] Fix more cases of stack overflow This patch moves the guard from parse_expr to parse_subexpr. This helps prevent us from overflowing the stack. Also added a test case for one such example where and expression contains a repeated +(unary plus) leading to a stackoverflow. --- src/parser/mod.rs | 2 +- tests/sqlparser_common.rs | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 977372656..061b1c9f0 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -874,12 +874,12 @@ impl<'a> Parser<'a> { /// Parse a new expression. pub fn parse_expr(&mut self) -> Result { - let _guard = self.recursion_counter.try_decrease()?; self.parse_subexpr(self.dialect.prec_unknown()) } /// Parse tokens until the precedence changes. pub fn parse_subexpr(&mut self, precedence: u8) -> Result { + let _guard = self.recursion_counter.try_decrease()?; debug!("parsing expr"); let mut expr = self.parse_prefix()?; debug!("prefix: {:?}", expr); diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index fbe97171b..f016ce1a4 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -8808,6 +8808,13 @@ fn parse_deeply_nested_parens_hits_recursion_limits() { assert_eq!(ParserError::RecursionLimitExceeded, res.unwrap_err()); } +#[test] +fn parse_deeply_nested_unary_op_hits_recursion_limits() { + let sql = format!("SELECT {}", "+".repeat(1000)); + let res = parse_sql_statements(&sql); + assert_eq!(ParserError::RecursionLimitExceeded, res.unwrap_err()); +} + #[test] fn parse_deeply_nested_expr_hits_recursion_limits() { let dialect = GenericDialect {};