Skip to content

Commit 7e59d4a

Browse files
committed
Address review comments
1 parent 28d062b commit 7e59d4a

File tree

1 file changed

+25
-26
lines changed

1 file changed

+25
-26
lines changed

ext/spl/spl_observer.c

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,9 @@ PHPAPI zend_class_entry *spl_ce_MultipleIterator;
4444

4545
PHPAPI zend_object_handlers spl_handler_SplObjectStorage;
4646

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
5150

5251
typedef struct _spl_SplObjectStorage { /* {{{ */
5352
HashTable storage;
@@ -149,16 +148,16 @@ static spl_SplObjectStorageElement *spl_object_storage_create_element(zend_objec
149148
static spl_SplObjectStorageElement *spl_object_storage_attach_handle(spl_SplObjectStorage *intern, zend_object *obj, zval *inf) /* {{{ */
150149
{
151150
uint32_t handle = obj->handle;
152-
zval *entry_zv;
151+
zval *entry_zv = zend_hash_index_lookup(&intern->storage, handle);
153152
spl_SplObjectStorageElement *pelement;
154-
entry_zv = zend_hash_index_lookup(&intern->storage, handle);
155153
ZEND_ASSERT(!(intern->flags & SOS_OVERRIDDEN_WRITE_DIMENSION));
156154

157155
if (Z_TYPE_P(entry_zv) != IS_NULL) {
158156
zval zv_inf;
159157
ZEND_ASSERT(Z_TYPE_P(entry_zv) == IS_PTR);
160158
pelement = Z_PTR_P(entry_zv);
161159
ZVAL_COPY_VALUE(&zv_inf, &pelement->inf);
160+
ZEND_ASSERT(Z_TYPE(zv_inf) != IS_REFERENCE);
162161
if (inf) {
163162
ZVAL_COPY(&pelement->inf, inf);
164163
} else {
@@ -169,7 +168,6 @@ static spl_SplObjectStorageElement *spl_object_storage_attach_handle(spl_SplObje
169168
return pelement;
170169
}
171170

172-
ZEND_ASSERT((GC_FLAGS(&intern->storage) & IS_ARRAY_PERSISTENT) == 0);
173171
pelement = spl_object_storage_create_element(obj, inf);
174172
ZVAL_PTR(entry_zv, pelement);
175173
return pelement;
@@ -193,6 +191,7 @@ spl_SplObjectStorageElement *spl_object_storage_attach(spl_SplObjectStorage *int
193191
if (pelement) {
194192
zval zv_inf;
195193
ZVAL_COPY_VALUE(&zv_inf, &pelement->inf);
194+
ZEND_ASSERT(Z_TYPE(zv_inf) != IS_REFERENCE);
196195
if (inf) {
197196
ZVAL_COPY(&pelement->inf, inf);
198197
} else {
@@ -247,8 +246,8 @@ void spl_object_storage_addall(spl_SplObjectStorage *intern, spl_SplObjectStorag
247246
intern->index = 0;
248247
} /* }}} */
249248

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)
252251

253252
static zend_object *spl_object_storage_new_ex(zend_class_entry *class_type, zend_object *orig) /* {{{ */
254253
{
@@ -275,14 +274,14 @@ static zend_object *spl_object_storage_new_ex(zend_class_entry *class_type, zend
275274
if (get_hash->common.scope != spl_ce_SplObjectStorage) {
276275
intern->fptr_get_hash = get_hash;
277276
}
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)) {
281280
intern->flags |= SOS_OVERRIDDEN_READ_DIMENSION;
282281
}
283282

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)) {
286285
intern->flags |= SOS_OVERRIDDEN_WRITE_DIMENSION;
287286
}
288287
}
@@ -401,20 +400,19 @@ static zend_object *spl_SplObjectStorage_new(zend_class_entry *class_type)
401400
}
402401
/* }}} */
403402

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) /* {{{ */
406405
{
407406
if (EXPECTED(!intern->fptr_get_hash)) {
408407
return zend_hash_index_find(&intern->storage, obj->handle) != NULL;
409408
}
410-
int found;
411409
zend_hash_key key;
412410
if (spl_object_storage_get_hash(&key, intern, obj) == FAILURE) {
413-
return 0;
411+
return true;
414412
}
415413

416414
ZEND_ASSERT(key.key);
417-
found = zend_hash_exists(&intern->storage, key.key);
415+
bool found = zend_hash_exists(&intern->storage, key.key);
418416
zend_string_release_ex(key.key, 0);
419417

420418
return found;
@@ -463,17 +461,18 @@ static zval *spl_object_storage_read_dimension(zend_object *object, zval *offset
463461
return zend_std_read_dimension(object, offset, type, rv);
464462
}
465463
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-
}
471464

472465
if (!element) {
466+
if (type == BP_VAR_IS) {
467+
return &EG(uninitialized_zval);
468+
}
473469
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Object not found");
474470
return NULL;
475471
} 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);
477476
return rv;
478477
}
479478
}
@@ -538,7 +537,7 @@ PHP_METHOD(SplObjectStorage, offsetGet)
538537
if (!element) {
539538
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Object not found");
540539
} else {
541-
RETURN_COPY_DEREF(&element->inf);
540+
RETURN_COPY(&element->inf);
542541
}
543542
} /* }}} */
544543

0 commit comments

Comments
 (0)