improve safety of fill_buffer - see issue #260
This commit is contained in:
parent
293e9cea32
commit
c06b18abed
|
|
@ -1,6 +1,6 @@
|
|||
use error::Result;
|
||||
use serde;
|
||||
use std::io;
|
||||
use std::{io, slice};
|
||||
|
||||
/// An optional Read trait for advanced Bincode usage.
|
||||
///
|
||||
|
|
@ -136,16 +136,32 @@ where
|
|||
R: io::Read,
|
||||
{
|
||||
fn fill_buffer(&mut self, length: usize) -> Result<()> {
|
||||
// We first reserve the space needed in our buffer.
|
||||
let current_length = self.temp_buffer.len();
|
||||
if length > current_length {
|
||||
self.temp_buffer.reserve_exact(length - current_length);
|
||||
}
|
||||
|
||||
// Then create a slice with the length as our desired length. This is
|
||||
// safe as long as we only write (no reads) to this buffer, because
|
||||
// `reserve_exact` above has allocated this space.
|
||||
let buf = unsafe {
|
||||
slice::from_raw_parts_mut(self.temp_buffer.as_mut_ptr(), length)
|
||||
};
|
||||
|
||||
// This method is assumed to properly handle slices which include
|
||||
// uninitialized bytes (as ours does). See discussion at the link below.
|
||||
// https://github.com/servo/bincode/issues/260
|
||||
self.reader.read_exact(buf)?;
|
||||
|
||||
// Only after `read_exact` successfully returns do we set the buffer
|
||||
// length. By doing this after the call to `read_exact`, we can avoid
|
||||
// exposing uninitialized memory in the case of `read_exact` returning
|
||||
// an error.
|
||||
unsafe {
|
||||
self.temp_buffer.set_len(length);
|
||||
}
|
||||
|
||||
self.reader.read_exact(&mut self.temp_buffer)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue