From a58afc098d440b1bc0856f8850f0ef7716b7183f Mon Sep 17 00:00:00 2001 From: Aaron O'Mullan Date: Thu, 5 May 2022 09:16:39 -0300 Subject: chore(serde_v8): V8Slice SAFETY (#14493) --- serde_v8/magic/v8slice.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'serde_v8') diff --git a/serde_v8/magic/v8slice.rs b/serde_v8/magic/v8slice.rs index d4101847e..6950e29d9 100644 --- a/serde_v8/magic/v8slice.rs +++ b/serde_v8/magic/v8slice.rs @@ -41,12 +41,26 @@ impl V8Slice { } fn as_slice(&self) -> &[u8] { + // SAFETY: v8::SharedRef is similar to Arc<[u8]>, + // it points to a fixed continuous slice of bytes on the heap. + // We assume it's initialized and thus safe to read (though may not contain meaningful data) unsafe { &*(&self.store[self.range.clone()] as *const _ as *const [u8]) } } - #[allow(clippy::cast_ref_to_mut)] fn as_slice_mut(&mut self) -> &mut [u8] { - unsafe { &mut *(&self.store[self.range.clone()] as *const _ as *mut [u8]) } + // SAFETY: v8::SharedRef is similar to Arc<[u8]>, + // it points to a fixed continuous slice of bytes on the heap. + // It's safe-ish to mutate concurrently because it can not be + // shrunk/grown/moved/reallocated, thus avoiding dangling refs (unlike a Vec). + // Concurrent writes can't lead to meaningful structural invalidation + // since we treat them as opaque buffers / "bags of bytes", + // concurrent mutation is simply an accepted fact of life. + // And in practice V8Slices also do not have overallping read/write phases. + // TLDR: permissive interior mutability on slices of bytes is "fine" + #[allow(clippy::cast_ref_to_mut)] + unsafe { + &mut *(&self.store[self.range.clone()] as *const _ as *mut [u8]) + } } } -- cgit v1.2.3