@@ -44,10 +44,9 @@ PHPAPI zend_class_entry *spl_ce_MultipleIterator;
44
44
45
45
PHPAPI zend_object_handlers spl_handler_SplObjectStorage ;
46
46
47
- typedef enum {
48
- SOS_OVERRIDDEN_READ_DIMENSION = 1 ,
49
- SOS_OVERRIDDEN_WRITE_DIMENSION = 2 ,
50
- } SplObjectStorageBitFlags ;
47
+ /* Bit flags for marking internal functionality overridden by SplObjectStorage subclasses. */
48
+ #define SOS_OVERRIDDEN_READ_DIMENSION 1
49
+ #define SOS_OVERRIDDEN_WRITE_DIMENSION 2
51
50
52
51
typedef struct _spl_SplObjectStorage { /* {{{ */
53
52
HashTable storage ;
@@ -149,16 +148,16 @@ static spl_SplObjectStorageElement *spl_object_storage_create_element(zend_objec
149
148
static spl_SplObjectStorageElement * spl_object_storage_attach_handle (spl_SplObjectStorage * intern , zend_object * obj , zval * inf ) /* {{{ */
150
149
{
151
150
uint32_t handle = obj -> handle ;
152
- zval * entry_zv ;
151
+ zval * entry_zv = zend_hash_index_lookup ( & intern -> storage , handle ) ;
153
152
spl_SplObjectStorageElement * pelement ;
154
- entry_zv = zend_hash_index_lookup (& intern -> storage , handle );
155
153
ZEND_ASSERT (!(intern -> flags & SOS_OVERRIDDEN_WRITE_DIMENSION ));
156
154
157
155
if (Z_TYPE_P (entry_zv ) != IS_NULL ) {
158
156
zval zv_inf ;
159
157
ZEND_ASSERT (Z_TYPE_P (entry_zv ) == IS_PTR );
160
158
pelement = Z_PTR_P (entry_zv );
161
159
ZVAL_COPY_VALUE (& zv_inf , & pelement -> inf );
160
+ ZEND_ASSERT (Z_TYPE (zv_inf ) != IS_REFERENCE );
162
161
if (inf ) {
163
162
ZVAL_COPY (& pelement -> inf , inf );
164
163
} else {
@@ -169,7 +168,6 @@ static spl_SplObjectStorageElement *spl_object_storage_attach_handle(spl_SplObje
169
168
return pelement ;
170
169
}
171
170
172
- ZEND_ASSERT ((GC_FLAGS (& intern -> storage ) & IS_ARRAY_PERSISTENT ) == 0 );
173
171
pelement = spl_object_storage_create_element (obj , inf );
174
172
ZVAL_PTR (entry_zv , pelement );
175
173
return pelement ;
@@ -193,6 +191,7 @@ spl_SplObjectStorageElement *spl_object_storage_attach(spl_SplObjectStorage *int
193
191
if (pelement ) {
194
192
zval zv_inf ;
195
193
ZVAL_COPY_VALUE (& zv_inf , & pelement -> inf );
194
+ ZEND_ASSERT (Z_TYPE (zv_inf ) != IS_REFERENCE );
196
195
if (inf ) {
197
196
ZVAL_COPY (& pelement -> inf , inf );
198
197
} else {
@@ -247,8 +246,8 @@ void spl_object_storage_addall(spl_SplObjectStorage *intern, spl_SplObjectStorag
247
246
intern -> index = 0 ;
248
247
} /* }}} */
249
248
250
- #define SPL_OBJECT_STORAGE_CLASS_HAS_OVERRIDE (class_type , method ) \
251
- (((zend_function *)zend_hash_str_find_ptr (&(class_type)->function_table, (method), sizeof((method)) - 1 ))->common.scope != spl_ce_SplObjectStorage)
249
+ #define SPL_OBJECT_STORAGE_CLASS_HAS_OVERRIDE (class_type , zstr_method ) \
250
+ (((zend_function *)zend_hash_find_ptr (&(class_type)->function_table, ZSTR_KNOWN(zstr_method) ))->common.scope != spl_ce_SplObjectStorage)
252
251
253
252
static zend_object * spl_object_storage_new_ex (zend_class_entry * class_type , zend_object * orig ) /* {{{ */
254
253
{
@@ -275,14 +274,14 @@ static zend_object *spl_object_storage_new_ex(zend_class_entry *class_type, zend
275
274
if (get_hash -> common .scope != spl_ce_SplObjectStorage ) {
276
275
intern -> fptr_get_hash = get_hash ;
277
276
}
278
- if (get_hash != NULL ||
279
- SPL_OBJECT_STORAGE_CLASS_HAS_OVERRIDE (class_type , "offsetget" ) ||
280
- SPL_OBJECT_STORAGE_CLASS_HAS_OVERRIDE (class_type , "offsetexists" )) {
277
+ if (intern -> fptr_get_hash != NULL ||
278
+ SPL_OBJECT_STORAGE_CLASS_HAS_OVERRIDE (class_type , ZEND_STR_OFFSETGET ) ||
279
+ SPL_OBJECT_STORAGE_CLASS_HAS_OVERRIDE (class_type , ZEND_STR_OFFSETEXISTS )) {
281
280
intern -> flags |= SOS_OVERRIDDEN_READ_DIMENSION ;
282
281
}
283
282
284
- if (get_hash != NULL ||
285
- SPL_OBJECT_STORAGE_CLASS_HAS_OVERRIDE (class_type , "offsetset" )) {
283
+ if (intern -> fptr_get_hash != NULL ||
284
+ SPL_OBJECT_STORAGE_CLASS_HAS_OVERRIDE (class_type , ZEND_STR_OFFSETSET )) {
286
285
intern -> flags |= SOS_OVERRIDDEN_WRITE_DIMENSION ;
287
286
}
288
287
}
@@ -401,20 +400,19 @@ static zend_object *spl_SplObjectStorage_new(zend_class_entry *class_type)
401
400
}
402
401
/* }}} */
403
402
404
- /* Returns 1 if the SplObjectStorage contains an entry for getHash(obj), even if the corresponding value is null. */
405
- int spl_object_storage_contains (spl_SplObjectStorage * intern , zend_object * obj ) /* {{{ */
403
+ /* Returns true if the SplObjectStorage contains an entry for getHash(obj), even if the corresponding value is null. */
404
+ bool spl_object_storage_contains (spl_SplObjectStorage * intern , zend_object * obj ) /* {{{ */
406
405
{
407
406
if (EXPECTED (!intern -> fptr_get_hash )) {
408
407
return zend_hash_index_find (& intern -> storage , obj -> handle ) != NULL ;
409
408
}
410
- int found ;
411
409
zend_hash_key key ;
412
410
if (spl_object_storage_get_hash (& key , intern , obj ) == FAILURE ) {
413
- return 0 ;
411
+ return true ;
414
412
}
415
413
416
414
ZEND_ASSERT (key .key );
417
- found = zend_hash_exists (& intern -> storage , key .key );
415
+ bool found = zend_hash_exists (& intern -> storage , key .key );
418
416
zend_string_release_ex (key .key , 0 );
419
417
420
418
return found ;
@@ -463,17 +461,18 @@ static zval *spl_object_storage_read_dimension(zend_object *object, zval *offset
463
461
return zend_std_read_dimension (object , offset , type , rv );
464
462
}
465
463
spl_SplObjectStorageElement * element = zend_hash_index_find_ptr (& intern -> storage , Z_OBJ_HANDLE_P (offset ));
466
- if (type == BP_VAR_IS ) {
467
- if (element == NULL ) {
468
- return & EG (uninitialized_zval );
469
- }
470
- }
471
464
472
465
if (!element ) {
466
+ if (type == BP_VAR_IS ) {
467
+ return & EG (uninitialized_zval );
468
+ }
473
469
zend_throw_exception_ex (spl_ce_UnexpectedValueException , 0 , "Object not found" );
474
470
return NULL ;
475
471
} else {
476
- ZVAL_COPY_DEREF (rv , & element -> inf );
472
+ /* This deliberately returns a non-reference, even for BP_VAR_W and BP_VAR_RW, to behave the same way as SplObjectStorage did when using the default zend_std_read_dimension behavior.
473
+ * i.e. This prevents taking a reference to an entry of SplObjectStorage because offsetGet would return a non-reference. */
474
+ ZEND_ASSERT (Z_TYPE (element -> inf ) != IS_REFERENCE );
475
+ ZVAL_COPY (rv , & element -> inf );
477
476
return rv ;
478
477
}
479
478
}
@@ -538,7 +537,7 @@ PHP_METHOD(SplObjectStorage, offsetGet)
538
537
if (!element ) {
539
538
zend_throw_exception_ex (spl_ce_UnexpectedValueException , 0 , "Object not found" );
540
539
} else {
541
- RETURN_COPY_DEREF (& element -> inf );
540
+ RETURN_COPY (& element -> inf );
542
541
}
543
542
} /* }}} */
544
543
0 commit comments