@@ -377,6 +377,8 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_r_helper(zend_array *ht, zval *dim,
377377 zend_ulong hval ;
378378 zend_string * offset_key ;
379379 zval * retval ;
380+ zend_execute_data * execute_data ;
381+ const zend_op * opline ;
380382
381383 if (Z_TYPE_P (dim ) == IS_REFERENCE ) {
382384 dim = Z_REFVAL_P (dim );
@@ -390,16 +392,91 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_r_helper(zend_array *ht, zval *dim,
390392 offset_key = Z_STR_P (dim );
391393 goto str_index ;
392394 case IS_UNDEF :
395+ /* The array may be destroyed while throwing the notice.
396+ * Temporarily increase the refcount to detect this situation. */
397+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE )) {
398+ GC_ADDREF (ht );
399+ }
400+ execute_data = EG (current_execute_data );
401+ opline = EX (opline );
393402 zend_jit_undefined_op_helper (EG (current_execute_data )-> opline -> op2 .var );
403+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && !GC_DELREF (ht )) {
404+ zend_array_destroy (ht );
405+ if (opline -> result_type & (IS_VAR | IS_TMP_VAR )) {
406+ if (EG (exception )) {
407+ ZVAL_UNDEF (EX_VAR (opline -> result .var ));
408+ } else {
409+ ZVAL_NULL (EX_VAR (opline -> result .var ));
410+ }
411+ }
412+ return ;
413+ }
414+ if (EG (exception )) {
415+ if (opline -> result_type & (IS_VAR | IS_TMP_VAR )) {
416+ ZVAL_UNDEF (EX_VAR (opline -> result .var ));
417+ }
418+ return ;
419+ }
394420 ZEND_FALLTHROUGH ;
395421 case IS_NULL :
396422 offset_key = ZSTR_EMPTY_ALLOC ();
397423 goto str_index ;
398424 case IS_DOUBLE :
399- hval = zend_dval_to_lval_safe (Z_DVAL_P (dim ));
425+ hval = zend_dval_to_lval (Z_DVAL_P (dim ));
426+ if (!zend_is_long_compatible (Z_DVAL_P (dim ), hval )) {
427+ /* The array may be destroyed while throwing the notice.
428+ * Temporarily increase the refcount to detect this situation. */
429+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE )) {
430+ GC_ADDREF (ht );
431+ }
432+ execute_data = EG (current_execute_data );
433+ opline = EX (opline );
434+ zend_incompatible_double_to_long_error (Z_DVAL_P (dim ));
435+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && !GC_DELREF (ht )) {
436+ zend_array_destroy (ht );
437+ if (opline -> result_type & (IS_VAR | IS_TMP_VAR )) {
438+ if (EG (exception )) {
439+ ZVAL_UNDEF (EX_VAR (opline -> result .var ));
440+ } else {
441+ ZVAL_NULL (EX_VAR (opline -> result .var ));
442+ }
443+ }
444+ return ;
445+ }
446+ if (EG (exception )) {
447+ if (opline -> result_type & (IS_VAR | IS_TMP_VAR )) {
448+ ZVAL_UNDEF (EX_VAR (opline -> result .var ));
449+ }
450+ return ;
451+ }
452+ }
400453 goto num_index ;
401454 case IS_RESOURCE :
455+ /* The array may be destroyed while throwing the notice.
456+ * Temporarily increase the refcount to detect this situation. */
457+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE )) {
458+ GC_ADDREF (ht );
459+ }
460+ execute_data = EG (current_execute_data );
461+ opline = EX (opline );
402462 zend_use_resource_as_offset (dim );
463+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && !GC_DELREF (ht )) {
464+ zend_array_destroy (ht );
465+ if (opline -> result_type & (IS_VAR | IS_TMP_VAR )) {
466+ if (EG (exception )) {
467+ ZVAL_UNDEF (EX_VAR (opline -> result .var ));
468+ } else {
469+ ZVAL_NULL (EX_VAR (opline -> result .var ));
470+ }
471+ }
472+ return ;
473+ }
474+ if (EG (exception )) {
475+ if (opline -> result_type & (IS_VAR | IS_TMP_VAR )) {
476+ ZVAL_UNDEF (EX_VAR (opline -> result .var ));
477+ }
478+ return ;
479+ }
403480 hval = Z_RES_HANDLE_P (dim );
404481 goto num_index ;
405482 case IS_FALSE :
@@ -442,6 +519,8 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_is_helper(zend_array *ht, zval *dim
442519 zend_ulong hval ;
443520 zend_string * offset_key ;
444521 zval * retval ;
522+ zend_execute_data * execute_data ;
523+ const zend_op * opline ;
445524
446525 if (Z_TYPE_P (dim ) == IS_REFERENCE ) {
447526 dim = Z_REFVAL_P (dim );
@@ -455,16 +534,91 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_is_helper(zend_array *ht, zval *dim
455534 offset_key = Z_STR_P (dim );
456535 goto str_index ;
457536 case IS_UNDEF :
537+ /* The array may be destroyed while throwing the notice.
538+ * Temporarily increase the refcount to detect this situation. */
539+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE )) {
540+ GC_ADDREF (ht );
541+ }
542+ execute_data = EG (current_execute_data );
543+ opline = EX (opline );
458544 zend_jit_undefined_op_helper (EG (current_execute_data )-> opline -> op2 .var );
545+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && !GC_DELREF (ht )) {
546+ zend_array_destroy (ht );
547+ if (opline -> result_type & (IS_VAR | IS_TMP_VAR )) {
548+ if (EG (exception )) {
549+ ZVAL_UNDEF (EX_VAR (opline -> result .var ));
550+ } else {
551+ ZVAL_NULL (EX_VAR (opline -> result .var ));
552+ }
553+ }
554+ return ;
555+ }
556+ if (EG (exception )) {
557+ if (opline -> result_type & (IS_VAR | IS_TMP_VAR )) {
558+ ZVAL_UNDEF (EX_VAR (opline -> result .var ));
559+ }
560+ return ;
561+ }
459562 ZEND_FALLTHROUGH ;
460563 case IS_NULL :
461564 offset_key = ZSTR_EMPTY_ALLOC ();
462565 goto str_index ;
463566 case IS_DOUBLE :
464- hval = zend_dval_to_lval_safe (Z_DVAL_P (dim ));
567+ hval = zend_dval_to_lval (Z_DVAL_P (dim ));
568+ if (!zend_is_long_compatible (Z_DVAL_P (dim ), hval )) {
569+ /* The array may be destroyed while throwing the notice.
570+ * Temporarily increase the refcount to detect this situation. */
571+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE )) {
572+ GC_ADDREF (ht );
573+ }
574+ execute_data = EG (current_execute_data );
575+ opline = EX (opline );
576+ zend_incompatible_double_to_long_error (Z_DVAL_P (dim ));
577+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && !GC_DELREF (ht )) {
578+ zend_array_destroy (ht );
579+ if (opline -> result_type & (IS_VAR | IS_TMP_VAR )) {
580+ if (EG (exception )) {
581+ ZVAL_UNDEF (EX_VAR (opline -> result .var ));
582+ } else {
583+ ZVAL_NULL (EX_VAR (opline -> result .var ));
584+ }
585+ }
586+ return ;
587+ }
588+ if (EG (exception )) {
589+ if (opline -> result_type & (IS_VAR | IS_TMP_VAR )) {
590+ ZVAL_UNDEF (EX_VAR (opline -> result .var ));
591+ }
592+ return ;
593+ }
594+ }
465595 goto num_index ;
466596 case IS_RESOURCE :
597+ /* The array may be destroyed while throwing the notice.
598+ * Temporarily increase the refcount to detect this situation. */
599+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE )) {
600+ GC_ADDREF (ht );
601+ }
602+ execute_data = EG (current_execute_data );
603+ opline = EX (opline );
467604 zend_use_resource_as_offset (dim );
605+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && !GC_DELREF (ht )) {
606+ zend_array_destroy (ht );
607+ if (opline -> result_type & (IS_VAR | IS_TMP_VAR )) {
608+ if (EG (exception )) {
609+ ZVAL_UNDEF (EX_VAR (opline -> result .var ));
610+ } else {
611+ ZVAL_NULL (EX_VAR (opline -> result .var ));
612+ }
613+ }
614+ return ;
615+ }
616+ if (EG (exception )) {
617+ if (opline -> result_type & (IS_VAR | IS_TMP_VAR )) {
618+ ZVAL_UNDEF (EX_VAR (opline -> result .var ));
619+ }
620+ return ;
621+ }
468622 hval = Z_RES_HANDLE_P (dim );
469623 goto num_index ;
470624 case IS_FALSE :
@@ -518,16 +672,55 @@ static int ZEND_FASTCALL zend_jit_fetch_dim_isset_helper(zend_array *ht, zval *d
518672 offset_key = Z_STR_P (dim );
519673 goto str_index ;
520674 case IS_UNDEF :
675+ /* The array may be destroyed while throwing the notice.
676+ * Temporarily increase the refcount to detect this situation. */
677+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE )) {
678+ GC_ADDREF (ht );
679+ }
521680 zend_jit_undefined_op_helper (EG (current_execute_data )-> opline -> op2 .var );
681+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && !GC_DELREF (ht )) {
682+ zend_array_destroy (ht );
683+ return 0 ;
684+ }
685+ if (EG (exception )) {
686+ return 0 ;
687+ }
522688 ZEND_FALLTHROUGH ;
523689 case IS_NULL :
524690 offset_key = ZSTR_EMPTY_ALLOC ();
525691 goto str_index ;
526692 case IS_DOUBLE :
527- hval = zend_dval_to_lval_safe (Z_DVAL_P (dim ));
693+ hval = zend_dval_to_lval (Z_DVAL_P (dim ));
694+ if (!zend_is_long_compatible (Z_DVAL_P (dim ), hval )) {
695+ /* The array may be destroyed while throwing the notice.
696+ * Temporarily increase the refcount to detect this situation. */
697+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE )) {
698+ GC_ADDREF (ht );
699+ }
700+ zend_incompatible_double_to_long_error (Z_DVAL_P (dim ));
701+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && !GC_DELREF (ht )) {
702+ zend_array_destroy (ht );
703+ return 0 ;
704+ }
705+ if (EG (exception )) {
706+ return 0 ;
707+ }
708+ }
528709 goto num_index ;
529710 case IS_RESOURCE :
711+ /* The array may be destroyed while throwing the notice.
712+ * Temporarily increase the refcount to detect this situation. */
713+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE )) {
714+ GC_ADDREF (ht );
715+ }
530716 zend_use_resource_as_offset (dim );
717+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && !GC_DELREF (ht )) {
718+ zend_array_destroy (ht );
719+ return 0 ;
720+ }
721+ if (EG (exception )) {
722+ return 0 ;
723+ }
531724 hval = Z_RES_HANDLE_P (dim );
532725 goto num_index ;
533726 case IS_FALSE :
0 commit comments