Skip to content

Commit efad44e

Browse files
authored
fix hang when parsing egregiously long integer (#77)
1 parent 34a96df commit efad44e

File tree

4 files changed

+17
-22
lines changed

4 files changed

+17
-22
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "jiter"
3-
version = "0.2.0"
3+
version = "0.2.1"
44
edition = "2021"
55
description = "Iterable JSON parser"
66
readme = "README.md"

src/number_decoder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,16 +224,16 @@ impl IntParse {
224224
// number is too big for i64, we need ot use a big int
225225
loop {
226226
let (chunk, new_index) = IntChunk::parse_big(data, index);
227+
if (new_index - start) > 4300 {
228+
return json_err!(NumberOutOfRange, start + 4301);
229+
}
227230
match chunk {
228231
IntChunk::Ongoing(value) => {
229232
big_value *= ONGOING_CHUNK_MULTIPLIER;
230233
big_value += value;
231234
index = new_index;
232235
}
233236
IntChunk::Done(value) => {
234-
if (new_index - start) > 4300 {
235-
return json_err!(NumberOutOfRange, start + 4301);
236-
}
237237
big_value *= POW_10[new_index - index];
238238
big_value += value;
239239
if !positive {

tests/main.rs

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -981,23 +981,18 @@ fn test_4300_int() {
981981
}
982982

983983
#[test]
984-
fn test_4302_int_err() {
985-
let json = (0..4302).map(|_| "9".to_string()).collect::<Vec<_>>().join("");
986-
let bytes = json.as_bytes();
987-
let e = JsonValue::parse(bytes, false).unwrap_err();
988-
assert_eq!(e.error_type, JsonErrorType::NumberOutOfRange);
989-
assert_eq!(e.index, 4301);
990-
assert_eq!(e.description(bytes), "number out of range at line 1 column 4302");
991-
}
992-
993-
#[test]
994-
fn test_5000_int_err() {
995-
let json = ["9"; 5000].join("");
996-
let bytes = json.as_bytes();
997-
let e = JsonValue::parse(bytes, false).unwrap_err();
998-
assert_eq!(e.error_type, JsonErrorType::NumberOutOfRange);
999-
assert_eq!(e.index, 4301);
1000-
assert_eq!(e.description(bytes), "number out of range at line 1 column 4302");
984+
fn test_big_int_errs() {
985+
for json in [
986+
&[b'9'; 4302][..],
987+
&[b'9'; 5900][..],
988+
// If the check is only done at the end, this will hang
989+
&[b'9'; 10usize.pow(7)][..],
990+
] {
991+
let e = JsonValue::parse(json, false).unwrap_err();
992+
assert_eq!(e.error_type, JsonErrorType::NumberOutOfRange);
993+
assert_eq!(e.index, 4301);
994+
assert_eq!(e.description(json), "number out of range at line 1 column 4302");
995+
}
1001996
}
1002997

1003998
#[test]

0 commit comments

Comments
 (0)