From 2e1f0143772319ca29db1771fd7d24c3680dc998 Mon Sep 17 00:00:00 2001 From: "Carson M." Date: Tue, 1 Oct 2024 11:42:37 -0500 Subject: [PATCH] feat: upgrade `ValueRef(Mut)` to `Value` --- src/value/mod.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/value/mod.rs b/src/value/mod.rs index e33f59e..3e092e9 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -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, 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) } } @@ -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, 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) } }