diff --git a/serde/src/json/de.rs b/serde/src/json/de.rs index 1d0bc8d94..a5ec279bb 100644 --- a/serde/src/json/de.rs +++ b/serde/src/json/de.rs @@ -249,7 +249,7 @@ impl Deserializer fn parse_exponent(&mut self, mut res: f64) -> Result { try!(self.bump()); - let mut exp = 0; + let mut exp: u64 = 0; let mut neg_exp = false; if self.ch_is(b'+') { @@ -267,8 +267,16 @@ impl Deserializer while !self.eof() { match self.ch_or_null() { c @ b'0' ... b'9' => { - exp *= 10; - exp += (c as i32) - (b'0' as i32); + macro_rules! try_or_invalid { + ($e: expr) => { + match $e { + Some(v) => v, + None => { return Err(self.error(ErrorCode::InvalidNumber)); } + } + } + } + exp = try_or_invalid!(exp.checked_mul(10)); + exp = try_or_invalid!(exp.checked_add((c as u64) - (b'0' as u64))); try!(self.bump()); } @@ -276,7 +284,7 @@ impl Deserializer } } - let exp: f64 = 10_f64.powi(exp); + let exp: f64 = 10_f64.powf(exp as f64); if neg_exp { res /= exp; } else { diff --git a/serde_tests/tests/test_json.rs b/serde_tests/tests/test_json.rs index 58f118dac..c29f82865 100644 --- a/serde_tests/tests/test_json.rs +++ b/serde_tests/tests/test_json.rs @@ -703,6 +703,7 @@ fn test_parse_number_errors() { ("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)), ("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)), ("777777777777777777777777777", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 20)), + ("1e777777777777777777777777777", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 22)), ]); }