Skip to content

Commit 40ab5c2

Browse files
committed
feat(alloc): add estrdup
1 parent 96555c4 commit 40ab5c2

File tree

3 files changed

+72
-2
lines changed

3 files changed

+72
-2
lines changed

allowed_bindings.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ bind! {
2525
_call_user_function_impl,
2626
_efree,
2727
_emalloc,
28+
_estrdup,
2829
_zend_executor_globals,
2930
_sapi_globals_struct,
3031
_sapi_module_struct,

src/alloc.rs

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
44
use cfg_if::cfg_if;
55

6-
use crate::ffi::{_efree, _emalloc};
7-
use std::{alloc::Layout, ffi::c_void};
6+
use crate::ffi::{_efree, _emalloc, _estrdup};
7+
use std::{alloc::Layout, ffi::{c_char, c_void, CString}};
88

99
/// Uses the PHP memory allocator to allocate request-bound memory.
1010
///
@@ -62,3 +62,71 @@ pub unsafe fn efree(ptr: *mut u8) {
6262
}
6363
}
6464
}
65+
66+
/// Duplicates a string using the PHP memory manager.
67+
///
68+
/// # Parameters
69+
///
70+
/// * `string` - The string to duplicate, which can be any type that can be
71+
/// converted into a `Vec<u8>`.
72+
///
73+
/// # Returns
74+
///
75+
/// A pointer to the duplicated string in the PHP memory manager.
76+
pub fn estrdup(string: impl Into<Vec<u8>>) -> *mut c_char {
77+
let string = unsafe {
78+
CString::from_vec_unchecked(string.into())
79+
}.into_raw();
80+
81+
let result = unsafe {
82+
#[cfg(php_debug)]
83+
{
84+
_estrdup(
85+
string,
86+
std::ptr::null_mut(),
87+
0,
88+
std::ptr::null_mut(),
89+
0,
90+
)
91+
}
92+
#[cfg(not(php_debug))]
93+
{
94+
_estrdup(string)
95+
}
96+
};
97+
98+
drop(unsafe { CString::from_raw(string) });
99+
result
100+
}
101+
102+
#[cfg(test)]
103+
#[cfg(feature = "embed")]
104+
mod test {
105+
use super::*;
106+
use std::ffi::CStr;
107+
use crate::embed::Embed;
108+
109+
#[test]
110+
fn test_emalloc() {
111+
Embed::run(|| {
112+
let layout = Layout::from_size_align(16, 8).unwrap();
113+
let ptr = emalloc(layout);
114+
assert!(!ptr.is_null());
115+
unsafe { efree(ptr) };
116+
});
117+
}
118+
119+
#[test]
120+
fn test_estrdup() {
121+
Embed::run(|| {
122+
let original = "Hello, world!";
123+
let duplicated = estrdup(original);
124+
assert!(!duplicated.is_null());
125+
126+
let duplicated_str = unsafe { CStr::from_ptr(duplicated) };
127+
assert_eq!(duplicated_str.to_str().unwrap(), original);
128+
129+
unsafe { efree(duplicated as *mut u8) }
130+
});
131+
}
132+
}

src/exception.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ mod tests {
342342
});
343343
}
344344

345+
#[cfg(feature = "anyhow")]
345346
#[test]
346347
fn test_from_anyhow() {
347348
Embed::run(|| {

0 commit comments

Comments
 (0)