diff --git a/src/de.rs b/src/de.rs index 378b71062..88d0f2624 100644 --- a/src/de.rs +++ b/src/de.rs @@ -451,30 +451,33 @@ impl<'de, R: Read<'de>> Deserializer { &mut self, positive: bool, mut significand: u64, - mut exponent: i32, + exponent_before_decimal_point: i32, ) -> Result { self.eat_char(); + let mut exponent_after_decimal_point = 0; while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) { let digit = (c - b'0') as u64; if overflow!(significand * 10 + digit, u64::max_value()) { + let exponent = exponent_before_decimal_point + exponent_after_decimal_point; return self.parse_decimal_overflow(positive, significand, exponent); } self.eat_char(); significand = significand * 10 + digit; - exponent -= 1; + exponent_after_decimal_point -= 1; } // Error if there is not at least one digit after the decimal point. - if exponent == 0 { + if exponent_after_decimal_point == 0 { match tri!(self.peek()) { Some(_) => return Err(self.peek_error(ErrorCode::InvalidNumber)), None => return Err(self.peek_error(ErrorCode::EofWhileParsingValue)), } } + let exponent = exponent_before_decimal_point + exponent_after_decimal_point; match tri!(self.peek_or_null()) { b'e' | b'E' => self.parse_exponent(positive, significand, exponent), _ => self.f64_from_parts(positive, significand, exponent), diff --git a/tests/regression/issue953.rs b/tests/regression/issue953.rs new file mode 100644 index 000000000..771aa5287 --- /dev/null +++ b/tests/regression/issue953.rs @@ -0,0 +1,9 @@ +use serde_json::Value; + +#[test] +fn test() { + let x1 = serde_json::from_str::("18446744073709551615."); + assert!(x1.is_err()); + let x2 = serde_json::from_str::("18446744073709551616."); + assert!(x2.is_err()); +}