fix: Mark all pointer manipulation as unsafe
See b43455fdd0468f067741a79a7031ba2fa907f0eb for rationale (cherry picked from commit b9996c6ddd3973cd419930210bf11a4d1bc6350b)
This commit is contained in:
parent
c986c09b8c
commit
d19dd45bbf
3 changed files with 43 additions and 19 deletions
|
|
@ -64,7 +64,10 @@ struct EvalStateRef {
|
||||||
eval_state: NonNull<raw::EvalState>,
|
eval_state: NonNull<raw::EvalState>,
|
||||||
}
|
}
|
||||||
impl EvalStateRef {
|
impl EvalStateRef {
|
||||||
fn as_ptr(&self) -> *mut raw::EvalState {
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This function is unsafe because it returns a raw pointer. The caller must ensure that the pointer is not used beyond the lifetime of the underlying [raw::EvalState].
|
||||||
|
unsafe fn as_ptr(&self) -> *mut raw::EvalState {
|
||||||
self.eval_state.as_ptr()
|
self.eval_state.as_ptr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -122,7 +125,11 @@ impl EvalState {
|
||||||
context,
|
context,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn raw_ptr(&self) -> *mut raw::EvalState {
|
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This function is unsafe because it returns a raw pointer. The caller must ensure that the pointer is not used beyond the lifetime of this `EvalState`.
|
||||||
|
pub unsafe fn raw_ptr(&self) -> *mut raw::EvalState {
|
||||||
self.eval_state.as_ptr()
|
self.eval_state.as_ptr()
|
||||||
}
|
}
|
||||||
pub fn store(&self) -> &Store {
|
pub fn store(&self) -> &Store {
|
||||||
|
|
@ -255,15 +262,15 @@ impl EvalState {
|
||||||
}
|
}
|
||||||
let attr_name = CString::new(attr_name)
|
let attr_name = CString::new(attr_name)
|
||||||
.with_context(|| "require_attrs_select: attrName contains null byte")?;
|
.with_context(|| "require_attrs_select: attrName contains null byte")?;
|
||||||
let v2 = unsafe {
|
unsafe {
|
||||||
check_call!(raw::get_attr_byname(
|
let v2 = check_call!(raw::get_attr_byname(
|
||||||
&mut self.context,
|
&mut self.context,
|
||||||
v.raw_ptr(),
|
v.raw_ptr(),
|
||||||
self.eval_state.as_ptr(),
|
self.eval_state.as_ptr(),
|
||||||
attr_name.as_ptr()
|
attr_name.as_ptr()
|
||||||
))
|
))?;
|
||||||
}?;
|
Ok(Value::new(v2))
|
||||||
Ok(Value::new(v2))
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate, require that the value is an attrset, and select an attribute by name.
|
/// Evaluate, require that the value is an attrset, and select an attribute by name.
|
||||||
|
|
@ -292,7 +299,7 @@ impl EvalState {
|
||||||
attr_name.as_ptr()
|
attr_name.as_ptr()
|
||||||
))
|
))
|
||||||
}?;
|
}?;
|
||||||
Ok(v2.map(Value::new))
|
Ok(v2.map(|x| unsafe { Value::new(x) }))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new value containing the passed string.
|
/// Create a new value containing the passed string.
|
||||||
|
|
@ -442,8 +449,8 @@ impl EvalState {
|
||||||
#[doc(alias = "nix_value_call_multi")]
|
#[doc(alias = "nix_value_call_multi")]
|
||||||
pub fn call_multi(&mut self, f: &Value, args: &[Value]) -> Result<Value> {
|
pub fn call_multi(&mut self, f: &Value, args: &[Value]) -> Result<Value> {
|
||||||
let value = self.new_value_uninitialized()?;
|
let value = self.new_value_uninitialized()?;
|
||||||
let mut args_ptrs = args.iter().map(|a| a.raw_ptr()).collect::<Vec<_>>();
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let mut args_ptrs = args.iter().map(|a| a.raw_ptr()).collect::<Vec<_>>();
|
||||||
check_call!(raw::value_call_multi(
|
check_call!(raw::value_call_multi(
|
||||||
&mut self.context,
|
&mut self.context,
|
||||||
self.eval_state.as_ptr(),
|
self.eval_state.as_ptr(),
|
||||||
|
|
@ -473,13 +480,13 @@ impl EvalState {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_value_uninitialized(&mut self) -> Result<Value> {
|
fn new_value_uninitialized(&mut self) -> Result<Value> {
|
||||||
let value = unsafe {
|
unsafe {
|
||||||
check_call!(raw::alloc_value(
|
let value = check_call!(raw::alloc_value(
|
||||||
&mut self.context,
|
&mut self.context,
|
||||||
self.eval_state.as_ptr()
|
self.eval_state.as_ptr()
|
||||||
))
|
))?;
|
||||||
}?;
|
Ok(Value::new(value))
|
||||||
Ok(Value::new(value))
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new Nix function that is implemented by a Rust function.
|
/// Create a new Nix function that is implemented by a Rust function.
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,11 @@ impl Value {
|
||||||
/// Take ownership of a new Value.
|
/// Take ownership of a new Value.
|
||||||
///
|
///
|
||||||
/// This does not call `nix_gc_incref`, but does call `nix_gc_decref` when dropped.
|
/// This does not call `nix_gc_incref`, but does call `nix_gc_decref` when dropped.
|
||||||
pub(crate) fn new(inner: *mut raw::Value) -> Self {
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The caller must ensure that the provided `inner` has a positive reference count, and that `inner` is not used after the returned `Value` is dropped.
|
||||||
|
pub(crate) unsafe fn new(inner: *mut raw::Value) -> Self {
|
||||||
Value {
|
Value {
|
||||||
inner: NonNull::new(inner).unwrap(),
|
inner: NonNull::new(inner).unwrap(),
|
||||||
}
|
}
|
||||||
|
|
@ -66,13 +70,20 @@ impl Value {
|
||||||
/// Borrow a reference to a Value.
|
/// Borrow a reference to a Value.
|
||||||
///
|
///
|
||||||
/// This calls `nix_gc_incref`, and the returned Value will call `nix_gc_decref` when dropped.
|
/// This calls `nix_gc_incref`, and the returned Value will call `nix_gc_decref` when dropped.
|
||||||
pub(crate) fn new_borrowed(inner: *mut raw::Value) -> Self {
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The caller must ensure that the provided `inner` has a positive reference count.
|
||||||
|
pub(crate) unsafe fn new_borrowed(inner: *mut raw::Value) -> Self {
|
||||||
let v = Value::new(inner);
|
let v = Value::new(inner);
|
||||||
unsafe { raw::value_incref(null_mut(), inner) };
|
unsafe { raw::value_incref(null_mut(), inner) };
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn raw_ptr(&self) -> *mut raw::Value {
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The caller must ensure that the returned pointer is not used after the `Value` is dropped.
|
||||||
|
pub(crate) unsafe fn raw_ptr(&self) -> *mut raw::Value {
|
||||||
self.inner.as_ptr()
|
self.inner.as_ptr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,10 @@ struct StoreRef {
|
||||||
inner: NonNull<raw::Store>,
|
inner: NonNull<raw::Store>,
|
||||||
}
|
}
|
||||||
impl StoreRef {
|
impl StoreRef {
|
||||||
pub fn ptr(&self) -> *mut raw::Store {
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The returned pointer is only valid as long as the `StoreRef` is alive.
|
||||||
|
pub unsafe fn ptr(&self) -> *mut raw::Store {
|
||||||
self.inner.as_ptr()
|
self.inner.as_ptr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +160,10 @@ impl Store {
|
||||||
Ok(store)
|
Ok(store)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn raw_ptr(&self) -> *mut raw::Store {
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The returned pointer is only valid as long as the `Store` is alive.
|
||||||
|
pub unsafe fn raw_ptr(&self) -> *mut raw::Store {
|
||||||
self.inner.ptr()
|
self.inner.ptr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue