@@ -2073,8 +2073,10 @@ ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_offset_write(HashTable *ht
2073
2073
GC_ADDREF (ht );
2074
2074
}
2075
2075
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
+ }
2078
2080
return NULL ;
2079
2081
}
2080
2082
if (EG (exception )) {
@@ -2095,8 +2097,10 @@ ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_index_write(HashTable *ht,
2095
2097
/* Key may be released while throwing the undefined index warning. */
2096
2098
zend_string_addref (offset );
2097
2099
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
+ }
2100
2104
retval = NULL ;
2101
2105
} else if (EG (exception )) {
2102
2106
retval = NULL ;
@@ -2245,6 +2249,80 @@ static zend_never_inline zend_uchar slow_index_convert(HashTable *ht, const zval
2245
2249
}
2246
2250
}
2247
2251
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
+
2248
2326
static zend_always_inline zval * zend_fetch_dimension_address_inner (HashTable * ht , const zval * dim , int dim_type , int type EXECUTE_DATA_DC )
2249
2327
{
2250
2328
zval * retval = NULL ;
@@ -2306,8 +2384,13 @@ static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht
2306
2384
goto try_again ;
2307
2385
} else {
2308
2386
zend_value val ;
2309
- zend_uchar t = slow_index_convert ( ht , dim , & val EXECUTE_DATA_CC ) ;
2387
+ zend_uchar t ;
2310
2388
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
+ }
2311
2394
if (t == IS_STRING ) {
2312
2395
offset_key = val .str ;
2313
2396
goto str_index ;
0 commit comments