@@ -13,7 +13,7 @@ use crate::ffi::{
1313 zend_stream_init_filename, ZEND_RESULT_CODE_SUCCESS ,
1414} ;
1515use crate :: types:: { ZendObject , Zval } ;
16- use crate :: zend:: { panic_wrapper, ExecutorGlobals } ;
16+ use crate :: zend:: { panic_wrapper, try_catch , ExecutorGlobals } ;
1717use parking_lot:: { const_rwlock, RwLock } ;
1818use std:: ffi:: { c_char, c_void, CString , NulError } ;
1919use 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
3441static 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