From ee38c9982f7ee54823299d5cc87aaaab10e5864c Mon Sep 17 00:00:00 2001 From: ju1ius Date: Sat, 26 Nov 2022 11:05:11 +0100 Subject: [PATCH] allows ZendStr to contain null bytes Closes #200 --- src/types/string.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/types/string.rs b/src/types/string.rs index dd9624aee4..12788753cd 100644 --- a/src/types/string.rs +++ b/src/types/string.rs @@ -3,7 +3,7 @@ use std::{ borrow::Cow, - convert::TryFrom, + convert::{TryFrom, TryInto}, ffi::{CStr, CString}, fmt::Debug, slice, @@ -80,8 +80,14 @@ impl ZendStr { /// /// let s = ZendStr::new("Hello, world!", false).unwrap(); /// ``` - pub fn new(str: &str, persistent: bool) -> Result> { - Ok(Self::from_c_str(&CString::new(str)?, persistent)) + pub fn new(str: impl AsRef<[u8]>, persistent: bool) -> Result> { + let s = str.as_ref(); + unsafe { + let ptr = ext_php_rs_zend_string_init(s.as_ptr().cast(), s.len(), persistent) + .as_mut() + .expect("Failed to allocate memory for new Zend string"); + Ok(ZBox::from_raw(ptr)) + } } /// Creates a new Zend string from a [`CStr`]. @@ -171,8 +177,18 @@ impl ZendStr { /// /// let s = ZendStr::new_interned("PHP", true); /// ``` - pub fn new_interned(str: &str, persistent: bool) -> Result> { - Ok(Self::interned_from_c_str(&CString::new(str)?, persistent)) + pub fn new_interned(str: impl AsRef<[u8]>, persistent: bool) -> Result> { + let _lock = INTERNED_LOCK.lock(); + let s = str.as_ref(); + let len: u64 = s.len().try_into().map_err(|_| Error::IntegerOverflow)?; + unsafe { + let init_interned = + zend_string_init_interned.expect("`zend_string_init_interned` not ready"); + let ptr = init_interned(s.as_ptr().cast(), len, persistent) + .as_mut() + .expect("Failed to allocate memory for new Zend string"); + Ok(ZBox::from_raw(ptr)) + } } /// Creates a new interned Zend string from a [`CStr`].