Skip to content

Commit

Permalink
Fix a use-after-free in reallocate.
Browse files Browse the repository at this point in the history
Also provide forward-compatibility for the move to `NonZero<Unique<T>>`
in the future and tweak some docs.
  • Loading branch information
reem committed Jan 28, 2015
1 parent 68778f2 commit a5cc3b5
Showing 1 changed file with 15 additions and 11 deletions.
26 changes: 15 additions & 11 deletions src/util/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ impl<T> Buffer<T> {
/// ```
pub fn new() -> Buffer<T> {
Buffer {
buffer: unsafe { NonZero::new(heap::EMPTY as *mut T) },
buffer: empty()
cap: 0
}
}

/// Create a new buffer with space for cap Ts.
///
/// Unlike `std::rt::heap::allocate`, cap == 0 is allowed.
///
/// ```
/// # use collect::util::buffer::Buffer;
///
Expand All @@ -63,6 +65,8 @@ impl<T> Buffer<T> {

/// Reallocate this buffer to fit a new number of Ts.
///
/// Unlike `std::rt::heap::reallocate`, cap == 0 is allowed.
///
/// ```
/// # use collect::util::buffer::Buffer;
///
Expand All @@ -73,17 +77,17 @@ impl<T> Buffer<T> {
/// assert_eq!(buffer.capacity(), 1024);
/// ```
pub fn reallocate(&mut self, cap: usize) {
*self = if self.cap == 0 || cap == 0 {
Buffer::allocate(cap)
if self.cap == 0 || cap == 0 {
// Safe to drop the old buffer because either it never
// allocated or we're getting rid of the allocation.
*self = Buffer::allocate(cap)
} else {
Buffer {
buffer: unsafe {
reallocate(self.buffer,
NonZero::new(self.cap),
NonZero::new(cap))
},
cap: cap
}
let buffer = mem::replace(&mut self.buffer, empty());
self.buffer = unsafe {
reallocate(buffer, NonZero::new(self.cap),
NonZero::new(cap))
};
self.cap = cap;
}
}

Expand Down

0 comments on commit a5cc3b5

Please sign in to comment.