@@ -2073,8 +2073,10 @@ ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_offset_write(HashTable *ht
20732073 GC_ADDREF (ht );
20742074 }
20752075 zend_undefined_offset (lval );
2076- if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && !GC_DELREF (ht )) {
2077- zend_array_destroy (ht );
2076+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && GC_DELREF (ht ) != 1 ) {
2077+ if (!GC_REFCOUNT (ht )) {
2078+ zend_array_destroy (ht );
2079+ }
20782080 return NULL ;
20792081 }
20802082 if (EG (exception )) {
@@ -2095,8 +2097,10 @@ ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_index_write(HashTable *ht,
20952097 /* Key may be released while throwing the undefined index warning. */
20962098 zend_string_addref (offset );
20972099 zend_undefined_index (offset );
2098- if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && !GC_DELREF (ht )) {
2099- zend_array_destroy (ht );
2100+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && GC_DELREF (ht ) != 1 ) {
2101+ if (!GC_REFCOUNT (ht )) {
2102+ zend_array_destroy (ht );
2103+ }
21002104 retval = NULL ;
21012105 } else if (EG (exception )) {
21022106 retval = NULL ;
@@ -2245,6 +2249,80 @@ static zend_never_inline zend_uchar slow_index_convert(HashTable *ht, const zval
22452249 }
22462250}
22472251
2252+ static zend_never_inline zend_uchar slow_index_convert_w (HashTable * ht , const zval * dim , zend_value * value EXECUTE_DATA_DC )
2253+ {
2254+ switch (Z_TYPE_P (dim )) {
2255+ case IS_UNDEF : {
2256+ /* The array may be destroyed while throwing the notice.
2257+ * Temporarily increase the refcount to detect this situation. */
2258+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE )) {
2259+ GC_ADDREF (ht );
2260+ }
2261+ ZVAL_UNDEFINED_OP2 ();
2262+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && GC_DELREF (ht ) != 1 ) {
2263+ if (!GC_REFCOUNT (ht )) {
2264+ zend_array_destroy (ht );
2265+ }
2266+ return IS_NULL ;
2267+ }
2268+ if (EG (exception )) {
2269+ return IS_NULL ;
2270+ }
2271+ ZEND_FALLTHROUGH ;
2272+ }
2273+ case IS_NULL :
2274+ value -> str = ZSTR_EMPTY_ALLOC ();
2275+ return IS_STRING ;
2276+ case IS_DOUBLE :
2277+ value -> lval = zend_dval_to_lval (Z_DVAL_P (dim ));
2278+ if (!zend_is_long_compatible (Z_DVAL_P (dim ), value -> lval )) {
2279+ /* The array may be destroyed while throwing the notice.
2280+ * Temporarily increase the refcount to detect this situation. */
2281+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE )) {
2282+ GC_ADDREF (ht );
2283+ }
2284+ zend_incompatible_double_to_long_error (Z_DVAL_P (dim ));
2285+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && GC_DELREF (ht ) != 1 ) {
2286+ if (!GC_REFCOUNT (ht )) {
2287+ zend_array_destroy (ht );
2288+ }
2289+ return IS_NULL ;
2290+ }
2291+ if (EG (exception )) {
2292+ return IS_NULL ;
2293+ }
2294+ }
2295+ return IS_LONG ;
2296+ case IS_RESOURCE :
2297+ /* The array may be destroyed while throwing the notice.
2298+ * Temporarily increase the refcount to detect this situation. */
2299+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE )) {
2300+ GC_ADDREF (ht );
2301+ }
2302+ zend_use_resource_as_offset (dim );
2303+ if (!(GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) && GC_DELREF (ht ) != 1 ) {
2304+ if (!GC_REFCOUNT (ht )) {
2305+ zend_array_destroy (ht );
2306+ }
2307+ return IS_NULL ;
2308+ }
2309+ if (EG (exception )) {
2310+ return IS_NULL ;
2311+ }
2312+ value -> lval = Z_RES_HANDLE_P (dim );
2313+ return IS_LONG ;
2314+ case IS_FALSE :
2315+ value -> lval = 0 ;
2316+ return IS_LONG ;
2317+ case IS_TRUE :
2318+ value -> lval = 1 ;
2319+ return IS_LONG ;
2320+ default :
2321+ zend_illegal_offset ();
2322+ return IS_NULL ;
2323+ }
2324+ }
2325+
22482326static zend_always_inline zval * zend_fetch_dimension_address_inner (HashTable * ht , const zval * dim , int dim_type , int type EXECUTE_DATA_DC )
22492327{
22502328 zval * retval = NULL ;
@@ -2306,8 +2384,13 @@ static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht
23062384 goto try_again ;
23072385 } else {
23082386 zend_value val ;
2309- zend_uchar t = slow_index_convert ( ht , dim , & val EXECUTE_DATA_CC ) ;
2387+ zend_uchar t ;
23102388
2389+ if (type != BP_VAR_W && type != BP_VAR_RW ) {
2390+ t = slow_index_convert (ht , dim , & val EXECUTE_DATA_CC );
2391+ } else {
2392+ t = slow_index_convert_w (ht , dim , & val EXECUTE_DATA_CC );
2393+ }
23112394 if (t == IS_STRING ) {
23122395 offset_key = val .str ;
23132396 goto str_index ;
0 commit comments