From cb7e9f87eb44e6da02ff39c12c71ae6dddad6bc0 Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Thu, 20 Apr 2017 22:11:28 -0700 Subject: [PATCH] fix buffer length bug --- src/de/mod.rs | 22 +++------------------- src/de/read.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/de/mod.rs b/src/de/mod.rs index bbba6c4..b98be7e 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -1,4 +1,3 @@ -use std::cmp; use std::io::Read; use std::marker::PhantomData; @@ -12,8 +11,6 @@ use self::read::BincodeRead; pub mod read; -const BLOCK_SIZE: usize = 65536; - /// A Deserializer that reads bytes from a buffer. /// /// This struct should rarely be used. @@ -53,22 +50,9 @@ impl<'de, R: BincodeRead<'de>, E: ByteOrder, S: SizeLimit> Deserializer } fn read_vec(&mut self) -> Result> { - let mut len: usize = try!(serde::Deserialize::deserialize(&mut *self)); - - let mut result = Vec::new(); - let mut off = 0; - while len > 0 { - let reserve = cmp::min(len, BLOCK_SIZE); - try!(self.read_bytes(reserve as u64)); - unsafe { - result.reserve(reserve); - result.set_len(off + reserve); - } - try!(self.reader.read_exact(&mut result[off..])); - len -= reserve; - off += reserve; - } - Ok(result) + let len: usize = try!(serde::Deserialize::deserialize(&mut *self)); + self.read_bytes(len as u64)?; + self.reader.get_byte_buffer(len) } fn read_string(&mut self) -> Result { diff --git a/src/de/read.rs b/src/de/read.rs index 68ee1c5..f39de64 100644 --- a/src/de/read.rs +++ b/src/de/read.rs @@ -9,6 +9,9 @@ pub trait BincodeRead<'storage>: IoRead { fn forward_read_str(&mut self, length: usize, visitor: V) -> Result where V: serde::de::Visitor<'storage>; + #[doc(hidden)] + fn get_byte_buffer(&mut self, length: usize) -> Result>; + #[doc(hidden)] fn forward_read_bytes>(&mut self, length: usize, visitor: V) -> Result where V: serde::de::Visitor<'storage>; @@ -74,6 +77,21 @@ impl <'storage> BincodeRead<'storage> for SliceReader<'storage> { self.slice = &self.slice[length..]; r } + + fn get_byte_buffer(&mut self, length: usize) -> Result> { + use ::ErrorKind; + if length > self.slice.len() { + return Err(Box::new(ErrorKind::InvalidEncoding { + desc: "string was not valid utf8", + detail: None, + })); + } + + let r = &self.slice[..length]; + self.slice = &self.slice[length..]; + Ok(r.to_vec()) + } + fn forward_read_bytes>(&mut self, length: usize, visitor: V) -> Result { use ::ErrorKind; if length > self.slice.len() { @@ -106,10 +124,24 @@ impl BincodeRead<'static> for IoReadReader where R: IoRead { let r = visitor.visit_str(string); r } + + fn get_byte_buffer(&mut self, length: usize) -> Result> { + let current_length = self.temp_buffer.len(); + if length > current_length{ + self.temp_buffer.reserve_exact(length - current_length); + unsafe { self.temp_buffer.set_len(length); } + } + + self.reader.read_exact(&mut self.temp_buffer[..length])?; + + Ok(self.temp_buffer[..length].to_vec()) + } + fn forward_read_bytes>(&mut self, length: usize, visitor: V) -> Result { let current_length = self.temp_buffer.len(); if length > current_length{ self.temp_buffer.reserve_exact(length - current_length); + unsafe { self.temp_buffer.set_len(length); } } self.reader.read_exact(&mut self.temp_buffer[..length])?;