Skip to content

Commit

Permalink
Fix buffer overflow bug in deflate::core::BitBuffer::flush (#47)
Browse files Browse the repository at this point in the history
* Fix buffer overflow bug in deflate::core::BitBuffer::flush

The problem is that this function does not check that there is enough space to fit a u64, it only checks that the starting position for the write is in bounds.
I have tried adding `assert!(pos.checked_add(8).unwrap() <= output.inner.get_ref().len());` before the unsafe part, but that regressed performance exactly as much as the fully safe version, so I went for the fully safe code.

* Support older rustc versions
  • Loading branch information
Shnatsel authored and oyvindln committed Jun 23, 2019
1 parent 759476f commit 7fc6d66
Showing 1 changed file with 10 additions and 5 deletions.
15 changes: 10 additions & 5 deletions miniz_oxide/src/deflate/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,11 +570,9 @@ impl BitBuffer {

fn flush(&mut self, output: &mut OutputBufferOxide) -> io::Result<()> {
let pos = output.inner.position() as usize;
let inner = &mut ((*output.inner.get_mut())[pos]) as *mut u8 as *mut u64;
// # Unsafe
// TODO: check unsafety
unsafe {
ptr::write_unaligned(inner, self.bit_buffer.to_le());
{ // isolation to please borrow checker
let inner = &mut (*output.inner.get_mut())[pos..pos+8];
inner.copy_from_slice(&u64_to_le_bytes(self.bit_buffer));
}
output.inner.seek(
SeekFrom::Current((self.bits_in >> 3) as i64),
Expand All @@ -585,6 +583,13 @@ impl BitBuffer {
}
}

#[inline]
/// Copy of u64::to_le_bytes() that is only available starting at Rust 1.32,
/// while we want to support older Rust versions
fn u64_to_le_bytes(num: u64) -> [u8; 8] {
unsafe { mem::transmute(num.to_le()) }
}

/// A struct containing data about huffman codes and symbol frequencies.
///
/// NOTE: Only the literal/lengths have enough symbols to actually use
Expand Down

0 comments on commit 7fc6d66

Please sign in to comment.