diff options
author | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2024-01-17 22:20:32 +0100 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2024-01-18 07:39:25 +0100 |
commit | 250828a6d25148d35d394975aa9f45e89c734013 (patch) | |
tree | 1af7715eb305c4754161eb85db48c13abd6a7562 /askama_parser/src/expr.rs | |
parent | 2c7759c0d0534dd9903ebd97b13c4c44320a9aad (diff) | |
download | askama-250828a6d25148d35d394975aa9f45e89c734013.tar.gz askama-250828a6d25148d35d394975aa9f45e89c734013.tar.bz2 askama-250828a6d25148d35d394975aa9f45e89c734013.zip |
Yield error on deep AST recursion
Diffstat (limited to 'askama_parser/src/expr.rs')
-rw-r--r-- | askama_parser/src/expr.rs | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/askama_parser/src/expr.rs b/askama_parser/src/expr.rs index 65a7835..4aa778a 100644 --- a/askama_parser/src/expr.rs +++ b/askama_parser/src/expr.rs @@ -214,14 +214,20 @@ impl<'a> Expr<'a> { Ok((i, res)) } - fn prefix(i: &'a str, level: Level) -> ParseResult<'a, Self> { - let (_, level) = level.nest(i)?; + fn prefix(i: &'a str, mut level: Level) -> ParseResult<'a, Self> { + let (_, nested) = level.nest(i)?; let (i, (ops, mut expr)) = pair(many0(ws(alt((tag("!"), tag("-"))))), |i| { - Suffix::parse(i, level) + Suffix::parse(i, nested) })(i)?; + for op in ops.iter().rev() { + // This is a rare place where we create recursion in the parsed AST + // without recursing the parser call stack. However, this can lead + // to stack overflows in drop glue when the AST is very deep. + level = level.nest(i)?.1; expr = Self::Unary(op, Box::new(expr)); } + Ok((i, expr)) } |