@@ -3677,6 +3677,11 @@ static void zend_ffi_throw_parser_error(const char *format, ...) /* {{{ */
36773677 va_list va ;
36783678 char * message = NULL ;
36793679
3680+ if (FFI_G (parse_failed )) {
3681+ /* An error was already reported, parsing only continues to unwind cleanly */
3682+ return ;
3683+ }
3684+
36803685 va_start (va , format );
36813686 zend_vspprintf (& message , 0 , format , va );
36823687
@@ -5752,20 +5757,22 @@ ZEND_GET_MODULE(ffi)
57525757/* parser callbacks */
57535758void zend_ffi_parser_error (const char * format , ...) /* {{{ */
57545759{
5755- va_list va ;
5756- char * message = NULL ;
5760+ if (!FFI_G (parse_failed )) {
5761+ va_list va ;
5762+ char * message = NULL ;
57575763
5758- va_start (va , format );
5759- zend_vspprintf (& message , 0 , format , va );
5764+ va_start (va , format );
5765+ zend_vspprintf (& message , 0 , format , va );
57605766
5761- if (EG (current_execute_data )) {
5762- zend_throw_exception (zend_ffi_parser_exception_ce , message , 0 );
5763- } else {
5764- zend_error (E_WARNING , "FFI Parser: %s" , message );
5765- }
5767+ if (EG (current_execute_data )) {
5768+ zend_throw_exception (zend_ffi_parser_exception_ce , message , 0 );
5769+ } else {
5770+ zend_error (E_WARNING , "FFI Parser: %s" , message );
5771+ }
57665772
5767- efree (message );
5768- va_end (va );
5773+ efree (message );
5774+ va_end (va );
5775+ }
57695776
57705777 LONGJMP (FFI_G (bailout ), FAILURE );
57715778}
@@ -5851,10 +5858,16 @@ static void zend_ffi_finalize_type(zend_ffi_dcl *dcl) /* {{{ */
58515858 case ZEND_FFI_DCL_FLOAT |ZEND_FFI_DCL_COMPLEX :
58525859 case ZEND_FFI_DCL_DOUBLE |ZEND_FFI_DCL_COMPLEX :
58535860 case ZEND_FFI_DCL_DOUBLE |ZEND_FFI_DCL_LONG |ZEND_FFI_DCL_COMPLEX :
5854- zend_ffi_parser_error ("Unsupported type _Complex at line %d" , FFI_G (line ));
5861+ zend_ffi_throw_parser_error ("Unsupported type _Complex at line %d" , FFI_G (line ));
5862+ /* Do not bail out here: callers may hold memory that is not owned by dcl yet.
5863+ * Continue with a placeholder type, zend_ffi_parse_*() report the failure. */
5864+ FFI_G (parse_failed ) = 1 ;
5865+ dcl -> type = (zend_ffi_type * )& zend_ffi_type_sint32 ;
58555866 break ;
58565867 default :
5857- zend_ffi_parser_error ("Unsupported type specifier combination at line %d" , FFI_G (line ));
5868+ zend_ffi_throw_parser_error ("Unsupported type specifier combination at line %d" , FFI_G (line ));
5869+ FFI_G (parse_failed ) = 1 ;
5870+ dcl -> type = (zend_ffi_type * )& zend_ffi_type_sint32 ;
58585871 break ;
58595872 }
58605873 dcl -> flags &= ~ZEND_FFI_DCL_TYPE_SPECIFIERS ;
0 commit comments