@@ -2147,8 +2147,10 @@ ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_offset_write(HashTable *ht
21472147 GC_ADDREF (ht );
21482148 }
21492149 zend_undefined_offset (lval );
2150- if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && !GC_DELREF (ht )) {
2151- zend_array_destroy (ht );
2150+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && GC_DELREF (ht ) != 1 ) {
2151+ if (!GC_REFCOUNT (ht )) {
2152+ zend_array_destroy (ht );
2153+ }
21522154 return NULL ;
21532155 }
21542156 if (EG (exception )) {
@@ -2169,8 +2171,10 @@ ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_index_write(HashTable *ht,
21692171 /* Key may be released while throwing the undefined index warning. */
21702172 zend_string_addref (offset );
21712173 zend_undefined_index (offset );
2172- if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && !GC_DELREF (ht )) {
2173- zend_array_destroy (ht );
2174+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && GC_DELREF (ht ) != 1 ) {
2175+ if (!GC_REFCOUNT (ht )) {
2176+ zend_array_destroy (ht );
2177+ }
21742178 retval = NULL ;
21752179 } else if (EG (exception )) {
21762180 retval = NULL ;
@@ -2319,6 +2323,80 @@ static zend_never_inline zend_uchar slow_index_convert(HashTable *ht, const zval
23192323 }
23202324}
23212325
2326+ static zend_never_inline zend_uchar slow_index_convert_w (HashTable * ht , const zval * dim , zend_value * value EXECUTE_DATA_DC )
2327+ {
2328+ switch (Z_TYPE_P (dim )) {
2329+ case IS_UNDEF : {
2330+ /* The array may be destroyed while throwing the notice.
2331+ * Temporarily increase the refcount to detect this situation. */
2332+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE )) {
2333+ GC_ADDREF (ht );
2334+ }
2335+ ZVAL_UNDEFINED_OP2 ();
2336+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && GC_DELREF (ht ) != 1 ) {
2337+ if (!GC_REFCOUNT (ht )) {
2338+ zend_array_destroy (ht );
2339+ }
2340+ return IS_NULL ;
2341+ }
2342+ if (EG (exception )) {
2343+ return IS_NULL ;
2344+ }
2345+ ZEND_FALLTHROUGH ;
2346+ }
2347+ case IS_NULL :
2348+ value -> str = ZSTR_EMPTY_ALLOC ();
2349+ return IS_STRING ;
2350+ case IS_DOUBLE :
2351+ value -> lval = zend_dval_to_lval (Z_DVAL_P (dim ));
2352+ if (!zend_is_long_compatible (Z_DVAL_P (dim ), value -> lval )) {
2353+ /* The array may be destroyed while throwing the notice.
2354+ * Temporarily increase the refcount to detect this situation. */
2355+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE )) {
2356+ GC_ADDREF (ht );
2357+ }
2358+ zend_incompatible_double_to_long_error (Z_DVAL_P (dim ));
2359+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && GC_DELREF (ht ) != 1 ) {
2360+ if (!GC_REFCOUNT (ht )) {
2361+ zend_array_destroy (ht );
2362+ }
2363+ return IS_NULL ;
2364+ }
2365+ if (EG (exception )) {
2366+ return IS_NULL ;
2367+ }
2368+ }
2369+ return IS_LONG ;
2370+ case IS_RESOURCE :
2371+ /* The array may be destroyed while throwing the notice.
2372+ * Temporarily increase the refcount to detect this situation. */
2373+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE )) {
2374+ GC_ADDREF (ht );
2375+ }
2376+ zend_use_resource_as_offset (dim );
2377+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && GC_DELREF (ht ) != 1 ) {
2378+ if (!GC_REFCOUNT (ht )) {
2379+ zend_array_destroy (ht );
2380+ }
2381+ return IS_NULL ;
2382+ }
2383+ if (EG (exception )) {
2384+ return IS_NULL ;
2385+ }
2386+ value -> lval = Z_RES_HANDLE_P (dim );
2387+ return IS_LONG ;
2388+ case IS_FALSE :
2389+ value -> lval = 0 ;
2390+ return IS_LONG ;
2391+ case IS_TRUE :
2392+ value -> lval = 1 ;
2393+ return IS_LONG ;
2394+ default :
2395+ zend_illegal_offset ();
2396+ return IS_NULL ;
2397+ }
2398+ }
2399+
23222400static zend_always_inline zval * zend_fetch_dimension_address_inner (HashTable * ht , const zval * dim , int dim_type , int type EXECUTE_DATA_DC )
23232401{
23242402 zval * retval = NULL ;
@@ -2380,8 +2458,13 @@ static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht
23802458 goto try_again ;
23812459 } else {
23822460 zend_value val ;
2383- zend_uchar t = slow_index_convert ( ht , dim , & val EXECUTE_DATA_CC ) ;
2461+ zend_uchar t ;
23842462
2463+ if (type != BP_VAR_W && type != BP_VAR_RW ) {
2464+ t = slow_index_convert (ht , dim , & val EXECUTE_DATA_CC );
2465+ } else {
2466+ t = slow_index_convert_w (ht , dim , & val EXECUTE_DATA_CC );
2467+ }
23852468 if (t == IS_STRING ) {
23862469 offset_key = val .str ;
23872470 goto str_index ;
0 commit comments