diff options
author | Aaron O'Mullan <aaron.omullan@gmail.com> | 2022-05-05 09:16:39 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-05 09:16:39 -0300 |
commit | a58afc098d440b1bc0856f8850f0ef7716b7183f (patch) | |
tree | 0dcb942a53daf231722270eb9b16ed958bfaa138 | |
parent | 45a4d75296b221240a2842bae0aef21622e21f97 (diff) |
chore(serde_v8): V8Slice SAFETY (#14493)
-rw-r--r-- | serde_v8/magic/v8slice.rs | 18 |
1 files changed, 16 insertions, 2 deletions
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<v8::BackingStore> 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<v8::BackingStore> 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]) + } } } |