From d87c2cf165049aed746cacd30bf78e7a29186717 Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Mon, 10 Feb 2020 14:10:48 -0500 Subject: [PATCH] Fix number parser grabbing comma --- src/lib.rs | 60 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b7b9af4..e5391f0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -262,15 +262,31 @@ impl JSON { n += 1; } else if self.chars[n] >= '1' && self.chars[n] <= '9' && n < max { n += 1; - while self.chars[n].is_ascii_digit() && n < max { - n += 1; + loop { + if n + 1 > max { + break; + } + + if self.chars[n + 1].is_ascii_digit() { + n += 1; + } else { + break; + } } } if self.chars[n] == '.' && n < max { n += 1; - while self.chars[n].is_ascii_digit() && n < max { - n += 1; + loop { + if n + 1 > max { + break; + } + + if self.chars[n + 1].is_ascii_digit() { + n += 1; + } else { + break; + } } } @@ -280,25 +296,36 @@ impl JSON { if self.chars[n] == '-' || self.chars[n] == '+' && n < max { n += 1; } + // expect digit + loop { + if n + 1 > max { + break; + } - while self.chars[n].is_ascii_digit() && n < max { - n += 1; + if self.chars[n + 1].is_ascii_digit() { + n += 1; + } else { + break; + } } } + // If there are numeric digits attempt to parse the digits as a number if n > start { let end = if n < self.chars.len() { n } else { - self.chars.len() + max }; let str = String::from_iter(&self.chars[start..=end]); - self.i += str.len() - 1; match str.parse::() { - Ok(n) => Ok(Some(JSONValue::Number(n))), - Err(e) => Err(ParseError::ExpectedDigit(format!("{:#?}", (str, e)))), + Ok(n) => { + self.increment(str.len() - 1); + return Ok(Some(JSONValue::Number(n))) + }, + Err(e) => Err(ParseError::ExpectedDigit(format!("'{}', {:#?}", str, e))), } } else { Ok(None) @@ -342,7 +369,7 @@ impl JSON { /// error is returned fn eat(&mut self, ch: char) -> Result<(), ParseError> { if self.chars[self.i] != ch { - let msg = format!("Expected '{}'.", ch); + let msg = format!("Expected {}.", ch); return Err(ParseError::ExpectedToken(msg)); } @@ -408,6 +435,9 @@ mod tests { #[test] fn parse_number() { + // This function works like I think, right? + assert_ne!(','.is_ascii_digit(), true); + let mut parser = JSON::new(r#""foo""#); let res = JSON::parse_number(&mut parser); assert_eq!(res, Ok(None)); @@ -419,6 +449,10 @@ mod tests { let mut parser = JSON::new("3e4"); let res = JSON::parse_number(&mut parser); assert_eq!(res, Ok(Some(JSONValue::Number(3e4f64)))); + + let mut parser = JSON::new("1.234,"); + let res = JSON::parse_number(&mut parser); + assert_eq!(res, Ok(Some(JSONValue::Number(1.234f64)))); } #[test] @@ -456,6 +490,9 @@ mod tests { #[test] fn can_parse_arbitrary_json() { + let result = JSON::parse("[{}]"); + assert_eq!(result, Ok(JSONValue::Array(vec![JSONValue::Object(HashMap::new())]))); + let result = JSON::parse( r#"[{ "a": 9.38083151965, @@ -472,7 +509,6 @@ mod tests { "i": ["\"", "\\", "/", "\b", "\f", "\n", "\r", "\t", "\u0001", "\uface"] }]"#, ); - // let msg = format!("{:#?}", result); assert!(result.is_ok(), format!("{:#?}", result)); } }