aboutsummaryrefslogtreecommitdiffstats
path: root/askama_parser/src/expr.rs
diff options
context:
space:
mode:
authorLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2024-01-17 22:20:32 +0100
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2024-01-18 07:39:25 +0100
commit250828a6d25148d35d394975aa9f45e89c734013 (patch)
tree1af7715eb305c4754161eb85db48c13abd6a7562 /askama_parser/src/expr.rs
parent2c7759c0d0534dd9903ebd97b13c4c44320a9aad (diff)
downloadaskama-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.rs12
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))
}