Skip to content

Commit de76f81

Browse files
committed
feat(try): add a test that expose memory leak problem
1 parent ffb83ed commit de76f81

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

src/embed/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ impl Embed {
111111
/// assert_eq!(foo.unwrap().string().unwrap(), "foo");
112112
/// });
113113
/// ```
114-
pub fn run<R, F: Fn() -> R + RefUnwindSafe>(func: F) -> R
114+
pub fn run<R, F: FnMut() -> R + RefUnwindSafe>(func: F) -> R
115115
where
116116
R: Default,
117117
{

src/zend/try_catch.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ use std::ptr::null_mut;
66
#[derive(Debug)]
77
pub struct CatchError;
88

9-
pub(crate) unsafe extern "C" fn panic_wrapper<R, F: Fn() -> R + RefUnwindSafe>(
9+
pub(crate) unsafe extern "C" fn panic_wrapper<R, F: FnMut() -> R + RefUnwindSafe>(
1010
ctx: *const c_void,
1111
) -> *const c_void {
1212
// we try to catch panic here so we correctly shutdown php if it happens
1313
// mandatory when we do assert on test as other test would not run correctly
14-
let panic = catch_unwind(|| (*(ctx as *const F))());
14+
let panic = catch_unwind(|| (*(ctx as *mut F))());
1515

1616
Box::into_raw(Box::new(panic)) as *mut c_void
1717
}
@@ -26,7 +26,7 @@ pub(crate) unsafe extern "C" fn panic_wrapper<R, F: Fn() -> R + RefUnwindSafe>(
2626
///
2727
/// * `Ok(R)` - The result of the function
2828
/// * `Err(CatchError)` - A bailout occurred during the execution
29-
pub fn try_catch<R, F: Fn() -> R + RefUnwindSafe>(func: F) -> Result<R, CatchError> {
29+
pub fn try_catch<R, F: FnMut() -> R + RefUnwindSafe>(func: F) -> Result<R, CatchError> {
3030
let mut panic_ptr = null_mut();
3131
let has_bailout = unsafe {
3232
ext_php_rs_zend_try_catch(
@@ -67,6 +67,7 @@ pub fn bailout() {
6767
mod tests {
6868
use crate::embed::Embed;
6969
use crate::zend::{bailout, try_catch};
70+
use std::ptr::null_mut;
7071

7172
#[test]
7273
fn test_catch() {
@@ -124,4 +125,21 @@ mod tests {
124125

125126
assert_eq!(foo, "foo");
126127
}
128+
129+
#[test]
130+
fn test_memory_leak() {
131+
let mut ptr = null_mut();
132+
133+
let _ = try_catch(|| {
134+
let mut result = "foo".to_string();
135+
ptr = &mut result;
136+
137+
bailout();
138+
});
139+
140+
// Check that the string is never released
141+
let result = unsafe { &*ptr as &str };
142+
143+
assert_eq!(result, "foo");
144+
}
127145
}

0 commit comments

Comments
 (0)