Skip to content

Commit d2225bd

Browse files
committed
Security: Enforce a (low) recursion limit
1 parent a673309 commit d2225bd

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

src/tokenizer.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,15 @@ pub struct Token<'a> {
2323
pub value: &'a str,
2424
}
2525

26+
const RECURSION_LIMIT: isize = 20;
27+
2628
#[derive(Debug, PartialEq)]
2729
pub struct TokenStream<'a> {
2830
buf: &'a str,
2931
position: Pos,
3032
off: usize,
3133
next_state: Option<(usize, Token<'a>, usize, Pos)>,
34+
recursion: isize,
3235
}
3336

3437
impl TokenStream<'_> {
@@ -133,6 +136,7 @@ impl<'a> TokenStream<'a> {
133136
position: Pos { line: 1, column: 1 },
134137
off: 0,
135138
next_state: None,
139+
recursion: 0,
136140
};
137141
me.skip_whitespace();
138142
me
@@ -148,6 +152,22 @@ impl<'a> TokenStream<'a> {
148152

149153
match cur_char {
150154
'!' | '$' | ':' | '=' | '@' | '|' | '(' | ')' | '[' | ']' | '{' | '}' | '&' => {
155+
match cur_char {
156+
'(' | '[' | '{' => {
157+
if self.recursion == RECURSION_LIMIT {
158+
return Err(Error::message_static_message("Recursion limit exceeded"));
159+
}
160+
self.recursion += 1;
161+
}
162+
')' | ']' | '}' => {
163+
// Note that this can go below 0.
164+
// We don't report that as an error here but
165+
// it would be caught by the parser
166+
self.recursion -= 1;
167+
}
168+
_ => {}
169+
}
170+
151171
self.position.column += 1;
152172
self.off += 1;
153173

0 commit comments

Comments
 (0)