From 1e21e5d13b21472e2d23ef08feb0ed4372295ef8 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 10 Mar 2016 17:08:11 +0800 Subject: [PATCH 1/2] Respect size limits in read_seq and read_map. --- src/rustc_serialize/reader.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/rustc_serialize/reader.rs b/src/rustc_serialize/reader.rs index d3dbfb3..7b2221d 100644 --- a/src/rustc_serialize/reader.rs +++ b/src/rustc_serialize/reader.rs @@ -129,7 +129,10 @@ impl<'a, R: Read> DecoderReader<'a, R> { impl <'a, A> DecoderReader<'a, A> { fn read_bytes(&mut self, count: u64) -> Result<(), DecodingError> { - self.read += count; + self.read = match self.read.checked_add(count) { + Some(read) => read, + None => return Err(DecodingError::SizeLimit), + }; match self.size_limit { SizeLimit::Infinite => Ok(()), SizeLimit::Bounded(x) if self.read <= x => Ok(()), @@ -342,6 +345,11 @@ impl<'a, R: Read> Decoder for DecoderReader<'a, R> { where F: FnOnce(&mut DecoderReader<'a, R>, usize) -> DecodingResult { let len = try!(self.read_usize()); + match self.size_limit { + SizeLimit::Infinite => (), + SizeLimit::Bounded(x) if self.read.saturating_add(len as u64) <= x => (), + SizeLimit::Bounded(_) => return Err(DecodingError::SizeLimit), + }; f(self, len) } fn read_seq_elt(&mut self, _: usize, f: F) -> DecodingResult @@ -353,6 +361,11 @@ impl<'a, R: Read> Decoder for DecoderReader<'a, R> { where F: FnOnce(&mut DecoderReader<'a, R>, usize) -> DecodingResult { let len = try!(self.read_usize()); + match self.size_limit { + SizeLimit::Infinite => (), + SizeLimit::Bounded(x) if self.read.saturating_add(len as u64) <= x => (), + SizeLimit::Bounded(_) => return Err(DecodingError::SizeLimit), + }; f(self, len) } fn read_map_elt_key(&mut self, _: usize, f: F) -> DecodingResult From ce61edb51f6433437a53ebe557b91c6f82dfa16b Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 10 Mar 2016 17:27:51 +0800 Subject: [PATCH 2/2] Replace use of saturating_add --- src/rustc_serialize/reader.rs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/rustc_serialize/reader.rs b/src/rustc_serialize/reader.rs index 7b2221d..1be8304 100644 --- a/src/rustc_serialize/reader.rs +++ b/src/rustc_serialize/reader.rs @@ -347,8 +347,15 @@ impl<'a, R: Read> Decoder for DecoderReader<'a, R> { let len = try!(self.read_usize()); match self.size_limit { SizeLimit::Infinite => (), - SizeLimit::Bounded(x) if self.read.saturating_add(len as u64) <= x => (), - SizeLimit::Bounded(_) => return Err(DecodingError::SizeLimit), + SizeLimit::Bounded(x) => { + let overflow = match self.read.checked_add(len as u64) { + Some(y) => y > x, + None => true, + }; + if overflow { + return Err(DecodingError::SizeLimit); + } + }, }; f(self, len) } @@ -363,8 +370,15 @@ impl<'a, R: Read> Decoder for DecoderReader<'a, R> { let len = try!(self.read_usize()); match self.size_limit { SizeLimit::Infinite => (), - SizeLimit::Bounded(x) if self.read.saturating_add(len as u64) <= x => (), - SizeLimit::Bounded(_) => return Err(DecodingError::SizeLimit), + SizeLimit::Bounded(x) => { + let overflow = match self.read.checked_add(len as u64) { + Some(y) => y > x, + None => true, + }; + if overflow { + return Err(DecodingError::SizeLimit); + } + }, }; f(self, len) }