@@ -2147,8 +2147,10 @@ ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_offset_write(HashTable *ht
2147
2147
GC_ADDREF (ht );
2148
2148
}
2149
2149
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
+ }
2152
2154
return NULL ;
2153
2155
}
2154
2156
if (EG (exception )) {
@@ -2169,8 +2171,10 @@ ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_index_write(HashTable *ht,
2169
2171
/* Key may be released while throwing the undefined index warning. */
2170
2172
zend_string_addref (offset );
2171
2173
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
+ }
2174
2178
retval = NULL ;
2175
2179
} else if (EG (exception )) {
2176
2180
retval = NULL ;
@@ -2319,6 +2323,80 @@ static zend_never_inline zend_uchar slow_index_convert(HashTable *ht, const zval
2319
2323
}
2320
2324
}
2321
2325
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
+
2322
2400
static zend_always_inline zval * zend_fetch_dimension_address_inner (HashTable * ht , const zval * dim , int dim_type , int type EXECUTE_DATA_DC )
2323
2401
{
2324
2402
zval * retval = NULL ;
@@ -2380,8 +2458,13 @@ static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht
2380
2458
goto try_again ;
2381
2459
} else {
2382
2460
zend_value val ;
2383
- zend_uchar t = slow_index_convert ( ht , dim , & val EXECUTE_DATA_CC ) ;
2461
+ zend_uchar t ;
2384
2462
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
+ }
2385
2468
if (t == IS_STRING ) {
2386
2469
offset_key = val .str ;
2387
2470
goto str_index ;
0 commit comments