Repository: serde-rs/json (language: rust)

Issue:
Invalid JSON values are accepted: numbers with trailing dot but only if greater than u64::MAX
According to JSON spec, both of these should be errors:

```rust
fn main() {
    let x1: Result<serde_json::Value, _> = serde_json::from_str("18446744073709551615.");
    assert!(x1.is_err());
    let x2: Result<serde_json::Value, _> = serde_json::from_str("18446744073709551616.");
    assert!(x2.is_err());
}
```

[Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=1d630973bd212fafadea90f3d2eabcf5)

But this is the output, as of serde_json 1.0.88:

```
thread 'main' panicked at 'assertion failed: x2.is_err()', src/main.rs:5:5
```


Discussion / hints:

Fix patch:
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<R> {
         &mut self,
         positive: bool,
         mut significand: u64,
-        mut exponent: i32,
+        exponent_before_decimal_point: i32,
     ) -> Result<f64> {
         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),


Test patch:
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::<Value>("18446744073709551615.");
+    assert!(x1.is_err());
+    let x2 = serde_json::from_str::<Value>("18446744073709551616.");
+    assert!(x2.is_err());
+}