Skip to content

Commit 5630975

Browse files
cuviperlauralt
authored andcommitted
Fix UB in MockBytesContainer
Miri flagged this as a retag error: error: Undefined Behavior: trying to retag from <wildcard> for Unique permission at alloc114820[0x0], but no exposed tags have suitable permission in the borrow stack for this location ... in the `slice::from_raw_parts_mut` via `&self`. This also manifested as a test failure in Fedora builds, which run tests in release mode: ---- bytes::tests::test_bytes stdout ---- thread 'bytes::tests::test_bytes' panicked at 'assertion failed: `(left == right)` left: `0`, right: `18446744073709551615`', src/bytes.rs:509:9 Using `RefCell` is simple way to get mutable access through `&self`, and the overhead of that runtime check is irrelevant for test-mocking. Signed-off-by: Josh Stone <[email protected]>
1 parent dbfa8fe commit 5630975

File tree

1 file changed

+7
-8
lines changed

1 file changed

+7
-8
lines changed

src/bytes.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,9 @@ pub(crate) mod tests {
334334
#![allow(clippy::undocumented_unsafe_blocks)]
335335
use super::*;
336336

337+
use std::cell::RefCell;
337338
use std::fmt::Debug;
338339
use std::mem::align_of;
339-
use std::slice;
340340

341341
// Helper method to test atomic accesses for a given `b: Bytes` that's supposed to be
342342
// zero-initialized.
@@ -410,13 +410,13 @@ pub(crate) mod tests {
410410
pub const MOCK_BYTES_CONTAINER_SIZE: usize = 10;
411411

412412
pub struct MockBytesContainer {
413-
container: [u8; MOCK_BYTES_CONTAINER_SIZE],
413+
container: RefCell<[u8; MOCK_BYTES_CONTAINER_SIZE]>,
414414
}
415415

416416
impl MockBytesContainer {
417417
pub fn new() -> Self {
418418
MockBytesContainer {
419-
container: [0; MOCK_BYTES_CONTAINER_SIZE],
419+
container: RefCell::new([0; MOCK_BYTES_CONTAINER_SIZE]),
420420
}
421421
}
422422

@@ -443,18 +443,17 @@ pub(crate) mod tests {
443443
fn write_slice(&self, buf: &[u8], addr: usize) -> Result<(), Self::E> {
444444
self.validate_slice_op(buf, addr)?;
445445

446-
// We need to get a mut reference to `self.container`.
447-
let container_ptr = self.container[addr..].as_ptr() as usize as *mut u8;
448-
let container = unsafe { slice::from_raw_parts_mut(container_ptr, buf.len()) };
449-
container.copy_from_slice(buf);
446+
let mut container = self.container.borrow_mut();
447+
container[addr..addr + buf.len()].copy_from_slice(buf);
450448

451449
Ok(())
452450
}
453451

454452
fn read_slice(&self, buf: &mut [u8], addr: usize) -> Result<(), Self::E> {
455453
self.validate_slice_op(buf, addr)?;
456454

457-
buf.copy_from_slice(&self.container[addr..buf.len()]);
455+
let container = self.container.borrow();
456+
buf.copy_from_slice(&container[addr..addr + buf.len()]);
458457

459458
Ok(())
460459
}

0 commit comments

Comments
 (0)