Skip to content

Commit e28c57e

Browse files
committed
feat(embed): add try catch on script / eval
1 parent e0c4c24 commit e28c57e

File tree

1 file changed

+30
-14
lines changed

1 file changed

+30
-14
lines changed

src/embed/mod.rs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::ffi::{
1313
zend_stream_init_filename, ZEND_RESULT_CODE_SUCCESS,
1414
};
1515
use crate::types::{ZendObject, Zval};
16-
use crate::zend::{panic_wrapper, ExecutorGlobals};
16+
use crate::zend::{panic_wrapper, try_catch, ExecutorGlobals};
1717
use parking_lot::{const_rwlock, RwLock};
1818
use std::ffi::{c_char, c_void, CString, NulError};
1919
use std::panic::{resume_unwind, RefUnwindSafe};
@@ -29,6 +29,13 @@ pub enum EmbedError {
2929
ExecuteScriptError,
3030
InvalidEvalString(NulError),
3131
InvalidPath,
32+
CatchError,
33+
}
34+
35+
impl EmbedError {
36+
pub fn is_bailout(&self) -> bool {
37+
matches!(self, EmbedError::CatchError)
38+
}
3239
}
3340

3441
static RUN_FN_LOCK: RwLock<()> = const_rwlock(());
@@ -79,10 +86,12 @@ impl Embed {
7986
zend_stream_init_filename(&mut file_handle, path.as_ptr());
8087
}
8188

82-
if unsafe { php_execute_script(&mut file_handle) } {
83-
Ok(())
84-
} else {
85-
Err(EmbedError::ExecuteScriptError)
89+
let exec_result = try_catch(|| unsafe { php_execute_script(&mut file_handle) });
90+
91+
match exec_result {
92+
Err(_) => Err(EmbedError::CatchError),
93+
Ok(true) => Ok(()),
94+
Ok(false) => Err(EmbedError::ExecuteScriptError),
8695
}
8796
}
8897

@@ -171,21 +180,18 @@ impl Embed {
171180

172181
let mut result = Zval::new();
173182

174-
// this eval is very limited as it only allow simple code, it's the same eval used by php -r
175-
let exec_result = unsafe {
183+
let exec_result = try_catch(|| unsafe {
176184
zend_eval_string(
177185
cstr.as_ptr() as *const c_char,
178186
&mut result,
179187
b"run\0".as_ptr() as *const _,
180188
)
181-
};
182-
183-
let exception = ExecutorGlobals::take_exception();
189+
});
184190

185-
if exec_result != ZEND_RESULT_CODE_SUCCESS {
186-
Err(EmbedError::ExecuteError(exception))
187-
} else {
188-
Ok(result)
191+
match exec_result {
192+
Err(_) => Err(EmbedError::CatchError),
193+
Ok(ZEND_RESULT_CODE_SUCCESS) => Ok(result),
194+
Ok(_) => Err(EmbedError::ExecuteError(ExecutorGlobals::take_exception())),
189195
}
190196
}
191197
}
@@ -254,4 +260,14 @@ mod tests {
254260

255261
assert_eq!(foo, "foo");
256262
}
263+
264+
#[test]
265+
fn test_eval_bailout() {
266+
Embed::run(|| {
267+
let result = Embed::eval("str_repeat('a', 100_000_000_000_000);");
268+
269+
assert!(result.is_err());
270+
assert!(result.unwrap_err().is_bailout());
271+
});
272+
}
257273
}

0 commit comments

Comments
 (0)