@@ -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,10 @@ 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 );
14681467
14691468 bool orig_record_errors = EG (record_errors );
14701469 EG (record_errors ) = false;
@@ -1478,8 +1477,9 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14781477
14791478 EG (user_error_handler_error_reporting ) = orig_user_error_handler_error_reporting ;
14801479 EG (record_errors ) = orig_record_errors ;
1481- EG (num_errors ) = num_errors ;
1482- EG (errors ) = errors ;
1480+ EG (errors -> size ) = num_errors ;
1481+ EG (errors -> capacity ) = cap_errors ;
1482+ memcpy (EG (errors -> buf ), errors , EG (errors -> capacity ) * sizeof (zend_error_info * ));
14831483 }
14841484
14851485 if (EG (record_errors )) {
@@ -1489,25 +1489,20 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14891489 info -> filename = zend_string_copy (error_filename );
14901490 info -> message = zend_string_copy (message );
14911491
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 ;
1492+ if (!EG (errors ) ) {
1493+ EG (errors ) = emalloc (sizeof (* EG (errors )) + 2 * sizeof (zend_error_info * ));
1494+ EG (errors -> capacity ) = 2 ;
1495+ EG (errors -> size ) = 1 ;
15001496 } 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 );
1497+ EG (errors -> size )++ ;
1498+ if (EG (errors -> size ) == EG (errors -> capacity )) {
15041499 // 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 ;
1500+ uint32_t capacity = EG (errors -> capacity ) + (EG (errors -> capacity ) >> 1 );
1501+ EG (errors ) = safe_erealloc (EG (errors ), sizeof (* EG (errors )) + capacity * sizeof (zend_error_info * ), 1 , 0 );
1502+ EG (errors -> capacity ) = capacity ;
15071503 }
15081504 }
1509- EG (errors ) = (zend_error_info * * )(errors_size + 1 );
1510- EG (errors )[EG (num_errors )- 1 ] = info ;
1505+ EG (errors -> buf )[EG (errors -> size )- 1 ] = info ;
15111506
15121507 /* Do not process non-fatal recorded error */
15131508 if (!(type & E_FATAL_ERRORS ) || (type & E_DONT_BAIL )) {
@@ -1590,17 +1585,23 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
15901585 }
15911586
15921587 orig_record_errors = EG (record_errors );
1593- orig_num_errors = EG (num_errors );
1594- orig_errors = EG (errors );
15951588 EG (record_errors ) = false;
1596- EG (num_errors ) = 0 ;
1597- EG (errors ) = NULL ;
1589+
1590+ if (EG (errors )) {
1591+ orig_num_errors = EG (errors -> size );
1592+ orig_cap_errors = EG (errors -> capacity );
1593+ orig_errors = EG (errors -> buf );
1594+ }
15981595
15991596 res = call_user_function (CG (function_table ), NULL , & orig_user_error_handler , & retval , 4 , params );
16001597
16011598 EG (record_errors ) = orig_record_errors ;
1602- EG (num_errors ) = orig_num_errors ;
1603- EG (errors ) = orig_errors ;
1599+
1600+ if (EG (errors )) {
1601+ EG (errors -> capacity ) = orig_cap_errors ;
1602+ EG (errors -> size ) = orig_num_errors ;
1603+ memcpy (EG (errors -> buf ), orig_errors , EG (errors -> capacity ) * sizeof (zend_error_info * ));
1604+ }
16041605
16051606 if (res == SUCCESS ) {
16061607 if (Z_TYPE (retval ) != IS_UNDEF ) {
@@ -1795,8 +1796,7 @@ ZEND_API void zend_begin_record_errors(void)
17951796{
17961797 ZEND_ASSERT (!EG (record_errors ) && "Error recording already enabled" );
17971798 EG (record_errors ) = true;
1798- EG (num_errors ) = 0 ;
1799- EG (errors ) = NULL ;
1799+ zend_free_recorded_errors ();
18001800}
18011801
18021802ZEND_API void zend_emit_recorded_errors_ex (uint32_t num_errors , zend_error_info * * errors )
@@ -1810,24 +1810,25 @@ ZEND_API void zend_emit_recorded_errors_ex(uint32_t num_errors, zend_error_info
18101810ZEND_API void zend_emit_recorded_errors (void )
18111811{
18121812 EG (record_errors ) = false;
1813- zend_emit_recorded_errors_ex (EG (num_errors ), EG (errors ));
1813+ if (EG (errors )) {
1814+ zend_emit_recorded_errors_ex (EG (errors -> size ), EG (errors -> buf ));
1815+ }
18141816}
18151817
18161818ZEND_API void zend_free_recorded_errors (void )
18171819{
1818- if (!EG (num_errors )) {
1820+ if (!EG (errors )) {
18191821 return ;
18201822 }
18211823
1822- for (uint32_t i = 0 ; i < EG (num_errors ); i ++ ) {
1823- zend_error_info * info = EG (errors )[i ];
1824+ for (uint32_t i = 0 ; i < EG (errors -> size ); i ++ ) {
1825+ zend_error_info * info = EG (errors -> buf )[i ];
18241826 zend_string_release (info -> filename );
18251827 zend_string_release (info -> message );
18261828 efree_size (info , sizeof (zend_error_info ));
18271829 }
1828- efree ((( size_t * ) EG (errors )) - 1 );
1830+ efree (EG (errors ));
18291831 EG (errors ) = NULL ;
1830- EG (num_errors ) = 0 ;
18311832}
18321833
18331834ZEND_API ZEND_COLD void zend_throw_error (zend_class_entry * exception_ce , const char * format , ...) /* {{{ */
0 commit comments