Skip to content

Commit 33521a5

Browse files
shuvamkclaude
andauthored
Add recursion checks for parse_interval (apache#2422)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent c4e7dc5 commit 33521a5

2 files changed

Lines changed: 17 additions & 0 deletions

File tree

src/parser/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3368,7 +3368,10 @@ impl<'a> Parser<'a> {
33683368
/// ```
33693369
///
33703370
/// Note that we do not currently attempt to parse the quoted value.
3371+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
33713372
pub fn parse_interval(&mut self) -> Result<Expr, ParserError> {
3373+
let _guard = self.recursion_counter.try_decrease()?;
3374+
33723375
// The SQL standard allows an optional sign before the value string, but
33733376
// it is not clear if any implementations support that syntax, so we
33743377
// don't currently try to parse it. (The sign can instead be included

tests/sqlparser_common.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11419,6 +11419,20 @@ fn parse_deeply_nested_subquery_expr_hits_recursion_limits() {
1141911419
assert_eq!(res, Err(ParserError::RecursionLimitExceeded));
1142011420
}
1142111421

11422+
#[test]
11423+
fn parse_deeply_nested_interval_hits_recursion_limits() {
11424+
let dialect = GenericDialect {};
11425+
11426+
let sql = format!("SELECT {}1", "INTERVAL ".repeat(1000));
11427+
11428+
let res = Parser::new(&dialect)
11429+
.try_with_sql(&sql)
11430+
.expect("tokenize to work")
11431+
.parse_statements();
11432+
11433+
assert_eq!(res, Err(ParserError::RecursionLimitExceeded));
11434+
}
11435+
1142211436
#[test]
1142311437
fn parse_with_recursion_limit() {
1142411438
let dialect = GenericDialect {};

0 commit comments

Comments
 (0)