@@ -833,8 +833,7 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{
833833#endif
834834 executor_globals -> flags = EG_FLAGS_INITIAL ;
835835 executor_globals -> record_errors = false;
836- executor_globals -> num_errors = 0 ;
837- executor_globals -> errors = NULL ;
836+ executor_globals -> errors = 0 ;
838837 executor_globals -> filename_override = NULL ;
839838 executor_globals -> lineno_override = -1 ;
840839#ifdef ZEND_CHECK_STACK_LIMIT
@@ -1447,8 +1446,9 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14471446 zend_stack delayed_oplines_stack ;
14481447 int type = orig_type & E_ALL ;
14491448 bool orig_record_errors ;
1450- uint32_t orig_num_errors ;
1451- zend_error_info * * orig_errors ;
1449+ uint32_t orig_num_errors = 0 ;
1450+ uint32_t orig_cap_errors = 0 ;
1451+ zend_error_info * * orig_errors = NULL ;
14521452 zend_result res ;
14531453
14541454 /* If we're executing a function during SCCP, count any warnings that may be emitted,
@@ -1460,11 +1460,12 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14601460 }
14611461
14621462 /* Emit any delayed error before handling fatal error */
1463- if ((type & E_FATAL_ERRORS ) && !(type & E_DONT_BAIL ) && EG (num_errors )) {
1464- uint32_t num_errors = EG (num_errors );
1465- zend_error_info * * errors = EG (errors );
1466- EG (num_errors ) = 0 ;
1467- EG (errors ) = NULL ;
1463+ if ((type & E_FATAL_ERRORS ) && !(type & E_DONT_BAIL ) && EG (errors )) {
1464+ uint32_t num_errors = EG (errors -> size );
1465+ uint32_t cap_errors = EG (errors -> capacity );
1466+ zend_error_info * * errors = EG (errors -> buf );
1467+ EG (errors -> size ) = 0 ;
1468+ EG (errors -> capacity ) = 0 ;
14681469
14691470 bool orig_record_errors = EG (record_errors );
14701471 EG (record_errors ) = false;
@@ -1478,8 +1479,9 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14781479
14791480 EG (user_error_handler_error_reporting ) = orig_user_error_handler_error_reporting ;
14801481 EG (record_errors ) = orig_record_errors ;
1481- EG (num_errors ) = num_errors ;
1482- EG (errors ) = errors ;
1482+ EG (errors -> size ) = num_errors ;
1483+ EG (errors -> capacity ) = cap_errors ;
1484+ memcpy (EG (errors -> buf ), errors , EG (errors -> capacity ) * sizeof (zend_error_info * ));
14831485 }
14841486
14851487 if (EG (record_errors )) {
@@ -1489,25 +1491,20 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14891491 info -> filename = zend_string_copy (error_filename );
14901492 info -> message = zend_string_copy (message );
14911493
1492- EG (num_errors )++ ;
1493- // pondering if uint32_t is more appropriate but would need to align the allocation size then
1494- size_t * errors_size ;
1495-
1496- if (EG (num_errors ) == 1 ) {
1497- errors_size = emalloc (sizeof (size_t ) + (2 * sizeof (zend_error_info * )));
1498- // can be seen as "waste" but to have a round even number from start
1499- * errors_size = 2 ;
1494+ if (!EG (errors ) ) {
1495+ EG (errors ) = emalloc (sizeof (* EG (errors )) + 2 * sizeof (zend_error_info * ));
1496+ EG (errors -> capacity ) = 2 ;
1497+ EG (errors -> size ) = 1 ;
15001498 } else {
1501- errors_size = (size_t * )(EG (errors ) - 1 );
1502- if (EG (num_errors ) == * errors_size ) {
1503- size_t tmp = * errors_size + (* errors_size >> 1 );
1499+ EG (errors -> size )++ ;
1500+ if (EG (errors -> size ) == EG (errors -> capacity )) {
15041501 // not sure we can get high number of errors so safe `might be` over cautious here
1505- errors_size = safe_erealloc (errors_size , sizeof (size_t ) + (tmp * sizeof (zend_error_info * )), 1 , 0 );
1506- * errors_size = tmp ;
1502+ uint32_t capacity = EG (errors -> capacity ) + (EG (errors -> capacity ) >> 1 );
1503+ EG (errors ) = safe_erealloc (EG (errors ), sizeof (* EG (errors )) + capacity * sizeof (zend_error_info * ), 1 , 0 );
1504+ EG (errors -> capacity ) = capacity ;
15071505 }
15081506 }
1509- EG (errors ) = (zend_error_info * * )(errors_size + 1 );
1510- EG (errors )[EG (num_errors )- 1 ] = info ;
1507+ EG (errors -> buf )[EG (errors -> size )- 1 ] = info ;
15111508
15121509 /* Do not process non-fatal recorded error */
15131510 if (!(type & E_FATAL_ERRORS ) || (type & E_DONT_BAIL )) {
@@ -1590,17 +1587,23 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
15901587 }
15911588
15921589 orig_record_errors = EG (record_errors );
1593- orig_num_errors = EG (num_errors );
1594- orig_errors = EG (errors );
15951590 EG (record_errors ) = false;
1596- EG (num_errors ) = 0 ;
1597- EG (errors ) = NULL ;
1591+
1592+ if (EG (errors )) {
1593+ orig_num_errors = EG (errors -> size );
1594+ orig_cap_errors = EG (errors -> capacity );
1595+ orig_errors = EG (errors -> buf );
1596+ }
15981597
15991598 res = call_user_function (CG (function_table ), NULL , & orig_user_error_handler , & retval , 4 , params );
16001599
16011600 EG (record_errors ) = orig_record_errors ;
1602- EG (num_errors ) = orig_num_errors ;
1603- EG (errors ) = orig_errors ;
1601+
1602+ if (EG (errors )) {
1603+ EG (errors -> capacity ) = orig_cap_errors ;
1604+ EG (errors -> size ) = orig_num_errors ;
1605+ memcpy (EG (errors -> buf ), orig_errors , EG (errors -> capacity ) * sizeof (zend_error_info * ));
1606+ }
16041607
16051608 if (res == SUCCESS ) {
16061609 if (Z_TYPE (retval ) != IS_UNDEF ) {
@@ -1795,8 +1798,7 @@ ZEND_API void zend_begin_record_errors(void)
17951798{
17961799 ZEND_ASSERT (!EG (record_errors ) && "Error recording already enabled" );
17971800 EG (record_errors ) = true;
1798- EG (num_errors ) = 0 ;
1799- EG (errors ) = NULL ;
1801+ zend_free_recorded_errors ();
18001802}
18011803
18021804ZEND_API void zend_emit_recorded_errors_ex (uint32_t num_errors , zend_error_info * * errors )
@@ -1810,24 +1812,25 @@ ZEND_API void zend_emit_recorded_errors_ex(uint32_t num_errors, zend_error_info
18101812ZEND_API void zend_emit_recorded_errors (void )
18111813{
18121814 EG (record_errors ) = false;
1813- zend_emit_recorded_errors_ex (EG (num_errors ), EG (errors ));
1815+ if (EG (errors )) {
1816+ zend_emit_recorded_errors_ex (EG (errors -> size ), EG (errors -> buf ));
1817+ }
18141818}
18151819
18161820ZEND_API void zend_free_recorded_errors (void )
18171821{
1818- if (!EG (num_errors )) {
1822+ if (!EG (errors )) {
18191823 return ;
18201824 }
18211825
1822- for (uint32_t i = 0 ; i < EG (num_errors ); i ++ ) {
1823- zend_error_info * info = EG (errors )[i ];
1826+ for (uint32_t i = 0 ; i < EG (errors -> size ); i ++ ) {
1827+ zend_error_info * info = EG (errors -> buf )[i ];
18241828 zend_string_release (info -> filename );
18251829 zend_string_release (info -> message );
18261830 efree_size (info , sizeof (zend_error_info ));
18271831 }
1828- efree ((( size_t * ) EG (errors )) - 1 );
1832+ efree (EG (errors ));
18291833 EG (errors ) = NULL ;
1830- EG (num_errors ) = 0 ;
18311834}
18321835
18331836ZEND_API ZEND_COLD void zend_throw_error (zend_class_entry * exception_ce , const char * format , ...) /* {{{ */
0 commit comments