Skip to content

Commit

Permalink
more error matching to serde
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelcolvin committed Oct 30, 2023
1 parent 9aa16aa commit 20920b5
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 35 deletions.
18 changes: 16 additions & 2 deletions fuzz/fuzz_targets/compare_to_serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,20 @@ fn remove_suffix(s: &str) -> &str {
}

fn errors_equal(jiter_error: &JiterError, serde_error: &SerdeError) -> bool {
remove_suffix(&jiter_error.to_string()) == remove_suffix(&serde_error.to_string())
let jiter_error_str = jiter_error.to_string();
let serde_error_str = serde_error.to_string();
if jiter_error_str.starts_with("invalid escape at") {
// strings like `"\"\\u\\"` give a EOF error for serde and invalid escape for jiter
true
} else if serde_error_str.starts_with("number out of range") {
// ignore this case as serde is stricter so fails on this before jiter does
true
} else if serde_error_str.starts_with("recursion limit exceeded") {
// serde has a different recursion limit to jiter
true
} else {
remove_suffix(&jiter_error_str) == remove_suffix(&serde_error_str)
}
}

fuzz_target!(|json: String| {
Expand All @@ -100,8 +113,9 @@ fuzz_target!(|json: String| {
if errors_equal(&jiter_error, &serde_error) {
return
} else {
dbg!(&jiter_error, jiter_error.to_string(), &serde_error, serde_error.to_string());
dbg!(json, &jiter_error, jiter_error.to_string(), &serde_error, serde_error.to_string());
panic!("errors not not equal");
// return
}
}
}
Expand Down
15 changes: 2 additions & 13 deletions src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,18 +92,7 @@ impl<'a> Parser<'a> {
}
}
} else {
json_err!(EofWhileParsingList, self.index)
}
}

pub fn peak_object_value(&mut self) -> JsonResult<Peak> {
if let Some(next) = self.eat_whitespace() {
match Peak::new(next) {
Some(p) => Ok(p),
None => json_err!(ExpectedSomeValue, self.index + 1),
}
} else {
json_err!(EofWhileParsingObject, self.index + 1)
json_err!(EofWhileParsingValue, self.index)
}
}

Expand Down Expand Up @@ -176,7 +165,7 @@ impl<'a> Parser<'a> {
Some(b'"') => self.object_key::<D>(tape).map(Some),
Some(b'}') => json_err!(TrailingComma, self.index + 1),
Some(_) => json_err!(KeyMustBeAString, self.index + 1),
None => json_err!(EofWhileParsingObject, self.index),
None => json_err!(EofWhileParsingValue, self.index),
}
}
b'}' => {
Expand Down
4 changes: 2 additions & 2 deletions src/python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ impl<'j> PythonParser<'j> {
let dict = PyDict::new(py);
if let Some(first_key) = self.parser.object_first::<StringDecoder>(&mut self.tape).map_err(mje)? {
let first_key = PyString::new(py, first_key);
let peak = self.parser.peak_object_value().map_err(mje)?;
let peak = self.parser.peak().map_err(mje)?;
let first_value = self._check_take_value(py, peak)?;
dict.set_item(first_key, first_value)?;
while let Some(key) = self.parser.object_step::<StringDecoder>(&mut self.tape).map_err(mje)? {
let key = PyString::new(py, key);
let peak = self.parser.peak_object_value().map_err(mje)?;
let peak = self.parser.peak().map_err(mje)?;
let value = self._check_take_value(py, peak)?;
dict.set_item(key, value)?;
}
Expand Down
4 changes: 2 additions & 2 deletions src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,14 @@ pub(crate) fn take_value(
let mut object = LazyIndexMap::new();
if let Some(first_key) = parser.object_first::<StringDecoder>(tape)? {
let first_key = first_key.to_string();
let peak = parser.peak_object_value()?;
let peak = parser.peak()?;
check_recursion!(recursion_limit, parser.index,
let first_value = take_value(peak, parser, tape, recursion_limit)?;
);
object.insert(first_key, first_value);
while let Some(key) = parser.object_step::<StringDecoder>(tape)? {
let key = key.to_string();
let peak = parser.peak_object_value()?;
let peak = parser.peak()?;
check_recursion!(recursion_limit, parser.index,
let value = take_value(peak, parser, tape, recursion_limit)?;
);
Expand Down
28 changes: 12 additions & 16 deletions tests/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,12 @@ use jiter::{
NumberInt, Parser, Peak, StringDecoder, StringDecoderRange,
};

enum PeakMode {
Start,
Array,
Object,
}

fn json_vec(parser: &mut Parser, peak_mode: PeakMode) -> JsonResult<Vec<String>> {
fn json_vec(parser: &mut Parser, in_array: bool) -> JsonResult<Vec<String>> {
let mut v = Vec::new();
let mut tape: Vec<u8> = Vec::new();
let peak = match peak_mode {
PeakMode::Start => parser.peak()?,
PeakMode::Array => parser.peak_array_step()?,
PeakMode::Object => parser.peak_object_value()?,
let peak = match in_array {
true => parser.peak_array_step()?,
false => parser.peak()?,
};

let position = parser.current_position().short();
Expand Down Expand Up @@ -52,7 +45,7 @@ fn json_vec(parser: &mut Parser, peak_mode: PeakMode) -> JsonResult<Vec<String>>
v.push(format!("[ @ {position}"));
if parser.array_first()?.is_some() {
loop {
let el_vec = json_vec(parser, PeakMode::Array)?;
let el_vec = json_vec(parser, true)?;
v.extend(el_vec);
if !parser.array_step()? {
break;
Expand All @@ -65,11 +58,11 @@ fn json_vec(parser: &mut Parser, peak_mode: PeakMode) -> JsonResult<Vec<String>>
v.push(format!("{{ @ {position}"));
if let Some(key) = parser.object_first::<StringDecoderRange>(&mut tape)? {
v.push(format!("Key({key:?})"));
let value_vec = json_vec(parser, PeakMode::Object)?;
let value_vec = json_vec(parser, false)?;
v.extend(value_vec);
while let Some(key) = parser.object_step::<StringDecoderRange>(&mut tape)? {
v.push(format!("Key({key:?}"));
let value_vec = json_vec(parser, PeakMode::Object)?;
let value_vec = json_vec(parser, false)?;
v.extend(value_vec);
}
}
Expand Down Expand Up @@ -103,7 +96,7 @@ macro_rules! single_expect_ok_or_error {
#[test]
fn [< single_element_ok__ $name >]() {
let mut parser = Parser::new($json.as_bytes());
let elements = json_vec(&mut parser, PeakMode::Start).unwrap().join(", ");
let elements = json_vec(&mut parser, false).unwrap().join(", ");
assert_eq!(elements, $expected);
parser.finish().unwrap();
}
Expand All @@ -116,7 +109,7 @@ macro_rules! single_expect_ok_or_error {
#[test]
fn [< single_element_xerror__ $name >]() {
let mut parser = Parser::new($json.as_bytes());
let result = json_vec(&mut parser, PeakMode::Start);
let result = json_vec(&mut parser, false);
let first_value = match result {
Ok(v) => v,
Err(e) => {
Expand Down Expand Up @@ -206,8 +199,11 @@ single_tests! {
object_trailing_comma: err => r#"{"foo": "bar",}"#, "TrailingComma @ 1:15";
array_trailing_comma: err => r#"[1, 2,]"#, "TrailingComma @ 1:7";
array_wrong_char_after_comma: err => r#"[1, 2,;"#, "ExpectedSomeValue @ 1:7";
array_end_after_comma: err => "[9,", "EofWhileParsingValue @ 1:3";
object_wrong_char: err => r#"{"foo":42;"#, "ExpectedObjectCommaOrEnd @ 1:10";
object_wrong_char_after_comma: err => r#"{"foo":42,;"#, "KeyMustBeAString @ 1:11";
object_end_after_comma: err => r#"{"x": 9,"#, "EofWhileParsingValue @ 1:8";
object_end_after_colon: err => r#"{"":"#, "EofWhileParsingValue @ 1:4";
array_bool: ok => "[true, false]", "[ @ 1:0, true @ 1:1, false @ 1:7, ]";
object_string: ok => r#"{"foo": "ba"}"#, "{ @ 1:0, Key(2..5), String(9..11) @ 1:8, }";
object_null: ok => r#"{"foo": null}"#, "{ @ 1:0, Key(2..5), null @ 1:8, }";
Expand Down

0 comments on commit 20920b5

Please sign in to comment.