From e6776ffc37f7d8053fd0c8a8304a54f282ccd7c0 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Mon, 18 May 2015 22:39:46 -0700 Subject: [PATCH] Protect against json integer overflow Closes #75 --- src/json/de.rs | 17 +++++++++++++---- tests/test_json.rs | 1 + 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/json/de.rs b/src/json/de.rs index e838ec75..1d0bc8d9 100644 --- a/src/json/de.rs +++ b/src/json/de.rs @@ -180,7 +180,7 @@ impl Deserializer } fn parse_integer(&mut self) -> Result { - let mut res = 0; + let mut accum: u64 = 0; match self.ch_or_null() { b'0' => { @@ -198,8 +198,17 @@ impl Deserializer while !self.eof() { match self.ch_or_null() { c @ b'0' ... b'9' => { - res *= 10; - res += (c as u64) - (b'0' as u64); + macro_rules! try_or_invalid { + ($e: expr) => { + match $e { + Some(v) => v, + None => { return Err(self.error(ErrorCode::InvalidNumber)); } + } + } + } + accum = try_or_invalid!(accum.checked_mul(10)); + accum = try_or_invalid!(accum.checked_add((c as u64) - ('0' as u64))); + try!(self.bump()); } _ => break, @@ -209,7 +218,7 @@ impl Deserializer _ => { return Err(self.error(ErrorCode::InvalidNumber)); } } - Ok(res) + Ok(accum) } fn parse_decimal(&mut self, res: f64) -> Result { diff --git a/tests/test_json.rs b/tests/test_json.rs index 65c73fd1..007afdad 100644 --- a/tests/test_json.rs +++ b/tests/test_json.rs @@ -708,6 +708,7 @@ fn test_parse_number_errors() { ("1e", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)), ("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)), ("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)), + ("777777777777777777777777777", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 20)), ]); }