Switch BufMut::bytes_mut to&mut UninitSlice (#433)

The way BufMut uses MaybeUninit can lead to unsoundness. This replaces
MaybeUnit with a type owned by bytes so we can ensure the usage patterns
are sound.

Refs: #328
This commit is contained in:
Carl Lerche
2020-10-19 15:48:23 -07:00
committed by GitHub
parent 79842672f4
commit 14b4e28a5f
8 changed files with 241 additions and 47 deletions
+29 -1
View File
@@ -1,5 +1,6 @@
#![warn(rust_2018_idioms)]
use bytes::buf::UninitSlice;
use bytes::{BufMut, BytesMut};
use core::fmt::Write;
use core::usize;
@@ -80,7 +81,7 @@ fn test_deref_bufmut_forwards() {
unreachable!("remaining_mut");
}
fn bytes_mut(&mut self) -> &mut [std::mem::MaybeUninit<u8>] {
fn bytes_mut(&mut self) -> &mut UninitSlice {
unreachable!("bytes_mut");
}
@@ -99,3 +100,30 @@ fn test_deref_bufmut_forwards() {
(Box::new(Special) as Box<dyn BufMut>).put_u8(b'x');
Box::new(Special).put_u8(b'x');
}
#[test]
#[should_panic]
fn write_byte_panics_if_out_of_bounds() {
let mut data = [b'b', b'a', b'r'];
let slice = unsafe { UninitSlice::from_raw_parts_mut(data.as_mut_ptr(), 3) };
slice.write_byte(4, b'f');
}
#[test]
#[should_panic]
fn copy_from_slice_panics_if_different_length_1() {
let mut data = [b'b', b'a', b'r'];
let slice = unsafe { UninitSlice::from_raw_parts_mut(data.as_mut_ptr(), 3) };
slice.copy_from_slice(b"a");
}
#[test]
#[should_panic]
fn copy_from_slice_panics_if_different_length_2() {
let mut data = [b'b', b'a', b'r'];
let slice = unsafe { UninitSlice::from_raw_parts_mut(data.as_mut_ptr(), 3) };
slice.copy_from_slice(b"abcd");
}
+2 -2
View File
@@ -912,12 +912,12 @@ fn bytes_buf_mut_advance() {
let mut bytes = BytesMut::with_capacity(1024);
unsafe {
let ptr = bytes.bytes_mut().as_ptr();
let ptr = bytes.bytes_mut().as_mut_ptr();
assert_eq!(1024, bytes.bytes_mut().len());
bytes.advance_mut(10);
let next = bytes.bytes_mut().as_ptr();
let next = bytes.bytes_mut().as_mut_ptr();
assert_eq!(1024 - 10, bytes.bytes_mut().len());
assert_eq!(ptr.offset(10), next);