refactor(core/rust): clarify safety of StrBuffer creation

grdddj/different_colors_for_old_display
matejcik 1 year ago committed by Martin Milata
parent b864ad58b2
commit e0bcdb16e0

@ -31,6 +31,19 @@ impl StrBuffer {
Self::from("")
}
// SAFETY:
// Caller is responsible for ensuring that data under `ptr` is valid for the
// whole lifetime of the result, plus possible copies/clones/offsets.
// This generally holds for GC-managed pointers and for static data.
// Dangerous with anything else.
pub unsafe fn from_ptr_and_len(ptr: *const u8, len: usize) -> Self {
Self {
ptr,
len: unwrap!(len.try_into()),
off: 0,
}
}
pub fn alloc(val: &str) -> Result<Self, Error> {
unsafe {
Self::alloc_with(val.len(), |buffer| {
@ -63,11 +76,8 @@ impl StrBuffer {
// Null-terminate the string for C ASCIIZ compatibility. This will not be
// reflected in Rust-visible slice, the zero byte is after the end.
raw.add(len).write(0);
Ok(Self {
ptr: raw,
len: unwrap!(len.try_into()),
off: 0,
})
// SAFETY: pointer is GC-managed.
Ok(Self::from_ptr_and_len(raw, len))
}
}
@ -107,11 +117,8 @@ impl TryFrom<Obj> for StrBuffer {
fn try_from(obj: Obj) -> Result<Self, Self::Error> {
if obj.is_str() {
let bufinfo = get_buffer_info(obj, ffi::MP_BUFFER_READ)?;
let new = Self {
ptr: bufinfo.buf as _,
len: bufinfo.len.try_into()?,
off: 0,
};
// SAFETY: bufinfo.buf should point to a GC head pointer or static data.
let new = unsafe { Self::from_ptr_and_len(bufinfo.buf as _, bufinfo.len) };
// MicroPython _should_ ensure that values of type `str` are UTF-8.
// Rust seems to be stricter in what it considers UTF-8 though.
@ -151,11 +158,9 @@ impl AsRef<str> for StrBuffer {
impl From<&'static str> for StrBuffer {
fn from(val: &'static str) -> Self {
Self {
ptr: val.as_ptr(),
len: unwrap!(val.len().try_into()),
off: 0,
}
// SAFETY: Safe for &'static strs.
// Do not try to do it with arbitrary &'a str.
unsafe { Self::from_ptr_and_len(val.as_ptr(), val.len()) }
}
}

Loading…
Cancel
Save