summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron O'Mullan <aaron.omullan@gmail.com>2022-05-05 09:16:39 -0300
committerGitHub <noreply@github.com>2022-05-05 09:16:39 -0300
commita58afc098d440b1bc0856f8850f0ef7716b7183f (patch)
tree0dcb942a53daf231722270eb9b16ed958bfaa138
parent45a4d75296b221240a2842bae0aef21622e21f97 (diff)
chore(serde_v8): V8Slice SAFETY (#14493)
-rw-r--r--serde_v8/magic/v8slice.rs18
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])
+ }
}
}