Skip to content

Commit

Permalink
fix hang when parsing egregiously long integer (#77)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt authored Apr 2, 2024
1 parent 34a96df commit efad44e
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 22 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "jiter"
version = "0.2.0"
version = "0.2.1"
edition = "2021"
description = "Iterable JSON parser"
readme = "README.md"
Expand Down
6 changes: 3 additions & 3 deletions src/number_decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,16 +224,16 @@ impl IntParse {
// number is too big for i64, we need ot use a big int
loop {
let (chunk, new_index) = IntChunk::parse_big(data, index);
if (new_index - start) > 4300 {
return json_err!(NumberOutOfRange, start + 4301);
}
match chunk {
IntChunk::Ongoing(value) => {
big_value *= ONGOING_CHUNK_MULTIPLIER;
big_value += value;
index = new_index;
}
IntChunk::Done(value) => {
if (new_index - start) > 4300 {
return json_err!(NumberOutOfRange, start + 4301);
}
big_value *= POW_10[new_index - index];
big_value += value;
if !positive {
Expand Down
29 changes: 12 additions & 17 deletions tests/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -981,23 +981,18 @@ fn test_4300_int() {
}

#[test]
fn test_4302_int_err() {
let json = (0..4302).map(|_| "9".to_string()).collect::<Vec<_>>().join("");
let bytes = json.as_bytes();
let e = JsonValue::parse(bytes, false).unwrap_err();
assert_eq!(e.error_type, JsonErrorType::NumberOutOfRange);
assert_eq!(e.index, 4301);
assert_eq!(e.description(bytes), "number out of range at line 1 column 4302");
}

#[test]
fn test_5000_int_err() {
let json = ["9"; 5000].join("");
let bytes = json.as_bytes();
let e = JsonValue::parse(bytes, false).unwrap_err();
assert_eq!(e.error_type, JsonErrorType::NumberOutOfRange);
assert_eq!(e.index, 4301);
assert_eq!(e.description(bytes), "number out of range at line 1 column 4302");
fn test_big_int_errs() {
for json in [
&[b'9'; 4302][..],
&[b'9'; 5900][..],
// If the check is only done at the end, this will hang
&[b'9'; 10usize.pow(7)][..],
] {
let e = JsonValue::parse(json, false).unwrap_err();
assert_eq!(e.error_type, JsonErrorType::NumberOutOfRange);
assert_eq!(e.index, 4301);
assert_eq!(e.description(json), "number out of range at line 1 column 4302");
}
}

#[test]
Expand Down

0 comments on commit efad44e

Please sign in to comment.