@@ -13,7 +13,7 @@ use crate::ffi::{
13
13
zend_stream_init_filename, ZEND_RESULT_CODE_SUCCESS ,
14
14
} ;
15
15
use crate :: types:: { ZendObject , Zval } ;
16
- use crate :: zend:: { panic_wrapper, ExecutorGlobals } ;
16
+ use crate :: zend:: { panic_wrapper, try_catch , ExecutorGlobals } ;
17
17
use parking_lot:: { const_rwlock, RwLock } ;
18
18
use std:: ffi:: { c_char, c_void, CString , NulError } ;
19
19
use std:: panic:: { resume_unwind, RefUnwindSafe } ;
@@ -29,6 +29,13 @@ pub enum EmbedError {
29
29
ExecuteScriptError ,
30
30
InvalidEvalString ( NulError ) ,
31
31
InvalidPath ,
32
+ CatchError ,
33
+ }
34
+
35
+ impl EmbedError {
36
+ pub fn is_bailout ( & self ) -> bool {
37
+ matches ! ( self , EmbedError :: CatchError )
38
+ }
32
39
}
33
40
34
41
static RUN_FN_LOCK : RwLock < ( ) > = const_rwlock ( ( ) ) ;
@@ -79,10 +86,12 @@ impl Embed {
79
86
zend_stream_init_filename ( & mut file_handle, path. as_ptr ( ) ) ;
80
87
}
81
88
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 ) ,
86
95
}
87
96
}
88
97
@@ -171,21 +180,18 @@ impl Embed {
171
180
172
181
let mut result = Zval :: new ( ) ;
173
182
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 {
176
184
zend_eval_string (
177
185
cstr. as_ptr ( ) as * const c_char ,
178
186
& mut result,
179
187
b"run\0 " . as_ptr ( ) as * const _ ,
180
188
)
181
- } ;
182
-
183
- let exception = ExecutorGlobals :: take_exception ( ) ;
189
+ } ) ;
184
190
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 ( ) ) ) ,
189
195
}
190
196
}
191
197
}
@@ -254,4 +260,14 @@ mod tests {
254
260
255
261
assert_eq ! ( foo, "foo" ) ;
256
262
}
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
+ }
257
273
}
0 commit comments