Skip to content

Commit

Permalink
feat: upgrade ValueRef(Mut) to Value
Browse files Browse the repository at this point in the history
  • Loading branch information
decahedron1 committed Oct 1, 2024
1 parent b1fb8c0 commit 2e1f014
Showing 1 changed file with 28 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,20 @@ impl<'v, Type: ValueTypeMarker + ?Sized> ValueRef<'v, Type> {
}
}

/// Attempts to upgrade this `ValueRef` to an owned [`Value`] holding the same data.
pub fn try_upgrade(self) -> Result<Value<Type>, Self> {
// We cannot upgade a value which we cannot drop, i.e. `ValueRef`s used in operator kernels. Those only last for the
// duration of the kernel, allowing an upgrade would allow a UAF.
if match &*self.inner.inner {
ValueInner::CppOwned { drop, .. } => !drop,
_ => false
} {
return Err(self);
}

Ok(ManuallyDrop::into_inner(self.inner))
}

pub fn into_dyn(self) -> ValueRef<'v, DynValueTypeMarker> {
unsafe { std::mem::transmute(self) }
}
Expand Down Expand Up @@ -304,6 +318,20 @@ impl<'v, Type: ValueTypeMarker + ?Sized> ValueRefMut<'v, Type> {
}
}

/// Attempts to upgrade this `ValueRefMut` to an owned [`Value`] holding the same data.
pub fn try_upgrade(self) -> Result<Value<Type>, Self> {
// We cannot upgade a value which we cannot drop, i.e. `ValueRef`s used in operator kernels. Those only last for the
// duration of the kernel, allowing an upgrade would allow a UAF.
if match &*self.inner.inner {
ValueInner::CppOwned { drop, .. } => !drop,
_ => false
} {
return Err(self);
}

Ok(ManuallyDrop::into_inner(self.inner))
}

pub fn into_dyn(self) -> ValueRefMut<'v, DynValueTypeMarker> {
unsafe { std::mem::transmute(self) }
}
Expand Down

0 comments on commit 2e1f014

Please sign in to comment.