Protect against json integer overflow

Closes #75
This commit is contained in:
Erick Tryzelaar 2015-05-18 22:39:46 -07:00
parent adae2bd3c5
commit e6776ffc37
2 changed files with 14 additions and 4 deletions

View File

@ -180,7 +180,7 @@ impl<Iter> Deserializer<Iter>
} }
fn parse_integer(&mut self) -> Result<u64, Error> { fn parse_integer(&mut self) -> Result<u64, Error> {
let mut res = 0; let mut accum: u64 = 0;
match self.ch_or_null() { match self.ch_or_null() {
b'0' => { b'0' => {
@ -198,8 +198,17 @@ impl<Iter> Deserializer<Iter>
while !self.eof() { while !self.eof() {
match self.ch_or_null() { match self.ch_or_null() {
c @ b'0' ... b'9' => { c @ b'0' ... b'9' => {
res *= 10; macro_rules! try_or_invalid {
res += (c as u64) - (b'0' as u64); ($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()); try!(self.bump());
} }
_ => break, _ => break,
@ -209,7 +218,7 @@ impl<Iter> Deserializer<Iter>
_ => { return Err(self.error(ErrorCode::InvalidNumber)); } _ => { return Err(self.error(ErrorCode::InvalidNumber)); }
} }
Ok(res) Ok(accum)
} }
fn parse_decimal(&mut self, res: f64) -> Result<f64, Error> { fn parse_decimal(&mut self, res: f64) -> Result<f64, Error> {

View File

@ -708,6 +708,7 @@ fn test_parse_number_errors() {
("1e", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)), ("1e", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)), ("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)), ("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)),
("777777777777777777777777777", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 20)),
]); ]);
} }