@@ -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+ memset (& executor_globals -> errors , 0 , sizeof (executor_globals -> errors ));
838837 executor_globals -> filename_override = NULL ;
839838 executor_globals -> lineno_override = -1 ;
840839#ifdef ZEND_CHECK_STACK_LIMIT
@@ -1446,8 +1445,7 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14461445 zend_stack delayed_oplines_stack ;
14471446 int type = orig_type & E_ALL ;
14481447 bool orig_record_errors ;
1449- uint32_t orig_num_errors ;
1450- zend_error_info * * orig_errors ;
1448+ zend_err_buf orig_errors_buf ;
14511449 zend_result res ;
14521450
14531451 /* If we're executing a function during SCCP, count any warnings that may be emitted,
@@ -1459,11 +1457,9 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14591457 }
14601458
14611459 /* Emit any delayed error before handling fatal error */
1462- if ((type & E_FATAL_ERRORS ) && !(type & E_DONT_BAIL ) && EG (num_errors )) {
1463- uint32_t num_errors = EG (num_errors );
1464- zend_error_info * * errors = EG (errors );
1465- EG (num_errors ) = 0 ;
1466- EG (errors ) = NULL ;
1460+ if ((type & E_FATAL_ERRORS ) && !(type & E_DONT_BAIL ) && EG (errors ).size ) {
1461+ zend_err_buf errors_buf = EG (errors );
1462+ EG (errors ).size = 0 ;
14671463
14681464 bool orig_record_errors = EG (record_errors );
14691465 EG (record_errors ) = false;
@@ -1473,12 +1469,11 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14731469 int orig_user_error_handler_error_reporting = EG (user_error_handler_error_reporting );
14741470 EG (user_error_handler_error_reporting ) = 0 ;
14751471
1476- zend_emit_recorded_errors_ex (num_errors , errors );
1472+ zend_emit_recorded_errors_ex (errors_buf . size , errors_buf . errors );
14771473
14781474 EG (user_error_handler_error_reporting ) = orig_user_error_handler_error_reporting ;
14791475 EG (record_errors ) = orig_record_errors ;
1480- EG (num_errors ) = num_errors ;
1481- EG (errors ) = errors ;
1476+ EG (errors ) = errors_buf ;
14821477 }
14831478
14841479 if (EG (record_errors )) {
@@ -1487,12 +1482,13 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14871482 info -> lineno = error_lineno ;
14881483 info -> filename = zend_string_copy (error_filename );
14891484 info -> message = zend_string_copy (message );
1490-
1491- /* This is very inefficient for a large number of errors.
1492- * Use pow2 realloc if it becomes a problem. */
1493- EG (num_errors )++ ;
1494- EG (errors ) = erealloc (EG (errors ), sizeof (zend_error_info * ) * EG (num_errors ));
1495- EG (errors )[EG (num_errors )- 1 ] = info ;
1485+ EG (errors ).size ++ ;
1486+ if (EG (errors ).size > EG (errors ).capacity ) {
1487+ uint32_t capacity = EG (errors ).capacity ? EG (errors ).capacity + (EG (errors ).capacity >> 1 ) : 2 ;
1488+ EG (errors ).errors = erealloc (EG (errors ).errors , sizeof (zend_error_info * ) * capacity );
1489+ EG (errors ).capacity = capacity ;
1490+ }
1491+ EG (errors ).errors [EG (errors ).size - 1 ] = info ;
14961492
14971493 /* Do not process non-fatal recorded error */
14981494 if (!(type & E_FATAL_ERRORS ) || (type & E_DONT_BAIL )) {
@@ -1575,17 +1571,15 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
15751571 }
15761572
15771573 orig_record_errors = EG (record_errors );
1578- orig_num_errors = EG (num_errors );
1579- orig_errors = EG (errors );
15801574 EG (record_errors ) = false;
1581- EG (num_errors ) = 0 ;
1582- EG (errors ) = NULL ;
1575+
1576+ orig_errors_buf = EG (errors );
1577+ memset (& EG (errors ), 0 , sizeof (EG (errors )));
15831578
15841579 res = call_user_function (CG (function_table ), NULL , & orig_user_error_handler , & retval , 4 , params );
15851580
15861581 EG (record_errors ) = orig_record_errors ;
1587- EG (num_errors ) = orig_num_errors ;
1588- EG (errors ) = orig_errors ;
1582+ EG (errors ) = orig_errors_buf ;
15891583
15901584 if (res == SUCCESS ) {
15911585 if (Z_TYPE (retval ) != IS_UNDEF ) {
@@ -1780,8 +1774,7 @@ ZEND_API void zend_begin_record_errors(void)
17801774{
17811775 ZEND_ASSERT (!EG (record_errors ) && "Error recording already enabled" );
17821776 EG (record_errors ) = true;
1783- EG (num_errors ) = 0 ;
1784- EG (errors ) = NULL ;
1777+ EG (errors ).size = 0 ;
17851778}
17861779
17871780ZEND_API void zend_emit_recorded_errors_ex (uint32_t num_errors , zend_error_info * * errors )
@@ -1795,24 +1788,23 @@ ZEND_API void zend_emit_recorded_errors_ex(uint32_t num_errors, zend_error_info
17951788ZEND_API void zend_emit_recorded_errors (void )
17961789{
17971790 EG (record_errors ) = false;
1798- zend_emit_recorded_errors_ex (EG (num_errors ) , EG (errors ));
1791+ zend_emit_recorded_errors_ex (EG (errors ). size , EG (errors ). errors );
17991792}
18001793
18011794ZEND_API void zend_free_recorded_errors (void )
18021795{
1803- if (!EG (num_errors ) ) {
1796+ if (!EG (errors ). size ) {
18041797 return ;
18051798 }
18061799
1807- for (uint32_t i = 0 ; i < EG (num_errors ) ; i ++ ) {
1808- zend_error_info * info = EG (errors )[i ];
1800+ for (uint32_t i = 0 ; i < EG (errors ). size ; i ++ ) {
1801+ zend_error_info * info = EG (errors ). errors [i ];
18091802 zend_string_release (info -> filename );
18101803 zend_string_release (info -> message );
1811- efree (info );
1804+ efree_size (info , sizeof ( zend_error_info ) );
18121805 }
1813- efree (EG (errors ));
1814- EG (errors ) = NULL ;
1815- EG (num_errors ) = 0 ;
1806+ efree (EG (errors ).errors );
1807+ memset (& EG (errors ), 0 , sizeof (EG (errors )));
18161808}
18171809
18181810ZEND_API ZEND_COLD void zend_throw_error (zend_class_entry * exception_ce , const char * format , ...) /* {{{ */
0 commit comments