diff --git a/src/args.rs b/src/args.rs index 7cd3f62d4..4bc928f1f 100644 --- a/src/args.rs +++ b/src/args.rs @@ -87,7 +87,7 @@ impl<'a> Arg<'a> { { self.zval .as_mut() - .and_then(|zv| T::from_zval_mut(zv)) + .and_then(|zv| T::from_zval_mut(zv.dereference_mut())) .ok_or(self) } @@ -98,7 +98,9 @@ impl<'a> Arg<'a> { where T: FromZvalMut<'a>, { - self.zval.as_mut().and_then(|zv| T::from_zval_mut(zv)) + self.zval + .as_mut() + .and_then(|zv| T::from_zval_mut(zv.dereference_mut())) } /// Attempts to return a reference to the arguments internal Zval. diff --git a/src/types/zval.rs b/src/types/zval.rs index f031214f3..d997d53d1 100644 --- a/src/types/zval.rs +++ b/src/types/zval.rs @@ -51,6 +51,25 @@ impl Zval { } } + /// Dereference the zval, if it is a reference. + pub fn dereference(&self) -> &Self { + return self.reference().or_else(|| self.indirect()).unwrap_or(self); + } + + /// Dereference the zval mutable, if it is a reference. + pub fn dereference_mut(&mut self) -> &mut Self { + // TODO: probably more ZTS work is needed here + if self.is_reference() { + #[allow(clippy::unwrap_used)] + return self.reference_mut().unwrap(); + } + if self.is_indirect() { + #[allow(clippy::unwrap_used)] + return self.indirect_mut().unwrap(); + } + self + } + /// Returns the value of the zval if it is a long. pub fn long(&self) -> Option { if self.is_long() { diff --git a/src/zend/_type.rs b/src/zend/_type.rs index 4342e3fcf..dc2ba4783 100644 --- a/src/zend/_type.rs +++ b/src/zend/_type.rs @@ -1,7 +1,4 @@ -use std::{ - ffi::{c_void, CString}, - ptr, -}; +use std::{ffi::c_void, ptr}; use crate::{ ffi::{ @@ -9,6 +6,7 @@ use crate::{ _ZEND_SEND_MODE_SHIFT, _ZEND_TYPE_NAME_BIT, _ZEND_TYPE_NULLABLE_BIT, }, flags::DataType, + types::ZendStr, }; /// Internal Zend type. @@ -82,7 +80,7 @@ impl ZendType { allow_null: bool, ) -> Option { Some(Self { - ptr: CString::new(class_name).ok()?.into_raw() as *mut c_void, + ptr: ZendStr::new(class_name, true).into_raw().as_ptr() as *mut c_void, type_mask: _ZEND_TYPE_NAME_BIT | (if allow_null { _ZEND_TYPE_NULLABLE_BIT diff --git a/src/zend/try_catch.rs b/src/zend/try_catch.rs index 2f0696ce7..5d3f56889 100644 --- a/src/zend/try_catch.rs +++ b/src/zend/try_catch.rs @@ -35,12 +35,13 @@ pub fn try_catch R + RefUnwindSafe>(func: F) -> Result