Skip to content

Commit

Permalink
try fix recursion limit calc
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed May 30, 2024
1 parent 8edf5e0 commit aa6b268
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 11 deletions.
19 changes: 8 additions & 11 deletions crates/jiter/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,15 +286,16 @@ fn take_value_skip_recursive(
let mut current_recursion_depth = 0;

macro_rules! push_recursion {
($value:expr) => {
if current_recursion_depth >= recursion_limit {
return Err(json_error!(RecursionLimitExceeded, parser.index));
}
($next_peek:expr, $value:expr) => {
peek = $next_peek;
recursion_stack.set(
current_recursion_depth,
std::mem::replace(&mut current_recursion, $value),
);
current_recursion_depth += 1
current_recursion_depth += 1;
if current_recursion_depth >= recursion_limit {
return Err(json_error!(RecursionLimitExceeded, parser.index));
}
};
}

Expand All @@ -308,18 +309,14 @@ fn take_value_skip_recursive(
}
Peek::Array => {
if let Some(next_peek) = parser.array_first()? {
push_recursion!(ARRAY);
peek = next_peek;

push_recursion!(next_peek, ARRAY);
// immediately jump to process the first value in the array
continue;
}
}
Peek::Object => {
if parser.object_first::<StringDecoderRange>(tape)?.is_some() {
push_recursion!(OBJECT);
peek = parser.peek()?;

push_recursion!(parser.peek()?, OBJECT);
// immediately jump to process the first value in the object
continue;
}
Expand Down
36 changes: 36 additions & 0 deletions crates/jiter/tests/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,42 @@ fn test_recursion_limit_incr() {
}
}

#[test]
fn test_recursion_limit_skip_array() {
let json = (0..2000).map(|_| "[ ").collect::<String>();
let bytes = json.as_bytes();
let mut jiter = Jiter::new(bytes);
let e = jiter.next_skip().unwrap_err();
assert_eq!(
e.error_type,
JiterErrorType::JsonError(JsonErrorType::RecursionLimitExceeded)
);
let expected_index = JsonValue::parse(bytes, false).unwrap_err().index;
assert_eq!(e.index, expected_index);
assert_eq!(
e.description(&jiter),
format!("recursion limit exceeded at line 1 column {}", expected_index + 1)
);
}

#[test]
fn test_recursion_limit_skip_object() {
let json = (0..2000).map(|_| "{\"a\": ").collect::<String>();
let bytes = json.as_bytes();
let mut jiter = Jiter::new(bytes);
let e = jiter.next_skip().unwrap_err();
assert_eq!(
e.error_type,
JiterErrorType::JsonError(JsonErrorType::RecursionLimitExceeded)
);
let expected_index = JsonValue::parse(bytes, false).unwrap_err().index;
assert_eq!(e.index, expected_index);
assert_eq!(
e.description(&jiter),
format!("recursion limit exceeded at line 1 column {}", expected_index + 1)
);
}

macro_rules! number_bytes {
($($name:ident: $json:literal => $expected:expr;)*) => {
$(
Expand Down

0 comments on commit aa6b268

Please sign in to comment.