avoid writing to readonly refcounts

This commit is contained in:
Brendan Hansknecht 2024-12-28 14:43:17 -08:00
parent 9b13b19d08
commit ad41b509cf
No known key found for this signature in database
GPG key ID: 0EA784685083E75B
2 changed files with 16 additions and 4 deletions

View file

@ -174,9 +174,12 @@ where
/// should be considered for marking read-only. /// should be considered for marking read-only.
pub unsafe fn set_readonly(&mut self) { pub unsafe fn set_readonly(&mut self) {
if let Some((_, storage)) = self.elements_and_storage() { if let Some((_, storage)) = self.elements_and_storage() {
// Only safe to write to the pointer if it is not constant (0)
if !matches!(storage.get(), Storage::Readonly) {
storage.set(Storage::Readonly); storage.set(Storage::Readonly);
} }
} }
}
/// Note that there is no way to convert directly to a Vec. /// Note that there is no way to convert directly to a Vec.
/// ///
@ -676,7 +679,10 @@ where
let ptr = self.ptr_to_refcount(); let ptr = self.ptr_to_refcount();
unsafe { unsafe {
let value = std::ptr::read(ptr); let value = std::ptr::read(ptr);
std::ptr::write(ptr, Ord::max(0, ((value as isize) + 1) as usize)); // Only safe to write to the pointer if it is not constant (0)
if value != 0 {
std::ptr::write(ptr, (value as isize + 1) as usize);
}
} }
} }

View file

@ -943,14 +943,20 @@ impl BigString {
assert_ne!(self.capacity(), 0); assert_ne!(self.capacity(), 0);
let ptr = self.ptr_to_refcount(); let ptr = self.ptr_to_refcount();
// Only safe to write to the pointer if it is not constant (0)
if unsafe { std::ptr::read(ptr) } != 0 {
unsafe { std::ptr::write(ptr, 0) } unsafe { std::ptr::write(ptr, 0) }
} }
}
fn inc(&mut self) { fn inc(&mut self) {
let ptr = self.ptr_to_refcount(); let ptr = self.ptr_to_refcount();
unsafe { unsafe {
let value = std::ptr::read(ptr); let value = std::ptr::read(ptr);
std::ptr::write(ptr, Ord::max(0, ((value as isize) + 1) as usize)); // Only safe to write to the pointer if it is not constant (0)
if value != 0 {
std::ptr::write(ptr, (value as isize + 1) as usize);
}
} }
} }