Skip to content

Commit ca8657a

Browse files
committed
Initialize SplFixedArray elements to NULL instead of UNDEF
The SplFixedArray API treats all elements as NULL, even if they have not been explicitly initialized. Rather than initializing to UNDEF an treating that specially in various circumstances, directly initialize elements to NULL. This also fixes an assertion failure in the attached test case.
1 parent b33697d commit ca8657a

File tree

2 files changed

+33
-31
lines changed

2 files changed

+33
-31
lines changed

ext/spl/spl_fixedarray.c

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,19 @@ static inline spl_fixedarray_object *spl_fixed_array_from_obj(zend_object *obj)
7676

7777
#define Z_SPLFIXEDARRAY_P(zv) spl_fixed_array_from_obj(Z_OBJ_P((zv)))
7878

79+
static inline void spl_fixedarray_init_elems(spl_fixedarray *array, size_t from, size_t to) {
80+
for (size_t i = from; i < to; i++) {
81+
ZVAL_NULL(&array->elements[i]);
82+
}
83+
}
84+
7985
static void spl_fixedarray_init(spl_fixedarray *array, zend_long size) /* {{{ */
8086
{
8187
if (size > 0) {
8288
array->size = 0; /* reset size in case ecalloc() fails */
83-
array->elements = ecalloc(size, sizeof(zval));
89+
array->elements = safe_emalloc(size, sizeof(zval), 0);
8490
array->size = size;
91+
spl_fixedarray_init_elems(array, 0, size);
8592
} else {
8693
array->elements = NULL;
8794
array->size = 0;
@@ -116,7 +123,7 @@ static void spl_fixedarray_resize(spl_fixedarray *array, zend_long size) /* {{{
116123
}
117124
} else if (size > array->size) {
118125
array->elements = safe_erealloc(array->elements, size, sizeof(zval), 0);
119-
memset(array->elements + array->size, '\0', sizeof(zval) * (size - array->size));
126+
spl_fixedarray_init_elems(array, array->size, size);
120127
} else { /* size < array->size */
121128
zend_long i;
122129

@@ -161,12 +168,8 @@ static HashTable* spl_fixedarray_object_get_properties(zend_object *obj) /* {{{{
161168
zend_long j = zend_hash_num_elements(ht);
162169

163170
for (i = 0; i < intern->array.size; i++) {
164-
if (!Z_ISUNDEF(intern->array.elements[i])) {
165-
zend_hash_index_update(ht, i, &intern->array.elements[i]);
166-
Z_TRY_ADDREF(intern->array.elements[i]);
167-
} else {
168-
zend_hash_index_update(ht, i, &EG(uninitialized_zval));
169-
}
171+
zend_hash_index_update(ht, i, &intern->array.elements[i]);
172+
Z_TRY_ADDREF(intern->array.elements[i]);
170173
}
171174
if (j > intern->array.size) {
172175
for (i = intern->array.size; i < j; ++i) {
@@ -323,8 +326,6 @@ static inline zval *spl_fixedarray_object_read_dimension_helper(spl_fixedarray_o
323326
if (index < 0 || index >= intern->array.size) {
324327
zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0);
325328
return NULL;
326-
} else if (Z_ISUNDEF(intern->array.elements[index])) {
327-
return NULL;
328329
} else {
329330
return &intern->array.elements[index];
330331
}
@@ -392,9 +393,7 @@ static inline void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_o
392393
zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0);
393394
return;
394395
} else {
395-
if (!Z_ISUNDEF(intern->array.elements[index])) {
396-
zval_ptr_dtor(&(intern->array.elements[index]));
397-
}
396+
zval_ptr_dtor(&(intern->array.elements[index]));
398397
ZVAL_COPY_DEREF(&intern->array.elements[index], value);
399398
}
400399
}
@@ -440,7 +439,7 @@ static inline void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_o
440439
return;
441440
} else {
442441
zval_ptr_dtor(&(intern->array.elements[index]));
443-
ZVAL_UNDEF(&intern->array.elements[index]);
442+
ZVAL_NULL(&intern->array.elements[index]);
444443
}
445444
}
446445
/* }}} */
@@ -459,7 +458,6 @@ static void spl_fixedarray_object_unset_dimension(zend_object *object, zval *off
459458
}
460459

461460
spl_fixedarray_object_unset_dimension_helper(intern, offset);
462-
463461
}
464462
/* }}} */
465463

@@ -477,16 +475,10 @@ static inline int spl_fixedarray_object_has_dimension_helper(spl_fixedarray_obje
477475
if (index < 0 || index >= intern->array.size) {
478476
retval = 0;
479477
} else {
480-
if (Z_ISUNDEF(intern->array.elements[index])) {
481-
retval = 0;
482-
} else if (check_empty) {
483-
if (zend_is_true(&intern->array.elements[index])) {
484-
retval = 1;
485-
} else {
486-
retval = 0;
487-
}
488-
} else { /* != NULL and !check_empty */
489-
retval = 1;
478+
if (check_empty) {
479+
retval = zend_is_true(&intern->array.elements[index]);
480+
} else {
481+
retval = Z_TYPE(intern->array.elements[index]) != IS_NULL;
490482
}
491483
}
492484

@@ -628,12 +620,8 @@ SPL_METHOD(SplFixedArray, toArray)
628620

629621
array_init(return_value);
630622
for (; i < intern->array.size; i++) {
631-
if (!Z_ISUNDEF(intern->array.elements[i])) {
632-
zend_hash_index_update(Z_ARRVAL_P(return_value), i, &intern->array.elements[i]);
633-
Z_TRY_ADDREF(intern->array.elements[i]);
634-
} else {
635-
zend_hash_index_update(Z_ARRVAL_P(return_value), i, &EG(uninitialized_zval));
636-
}
623+
zend_hash_index_update(Z_ARRVAL_P(return_value), i, &intern->array.elements[i]);
624+
Z_TRY_ADDREF(intern->array.elements[i]);
637625
}
638626
} else {
639627
RETURN_EMPTY_ARRAY();
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
SplFixedArray indirect modification notice
3+
--FILE--
4+
<?php
5+
$a = new SplFixedArray(1);
6+
$a[0][] = 3;
7+
var_dump($a);
8+
?>
9+
--EXPECTF--
10+
Notice: Indirect modification of overloaded element of SplFixedArray has no effect in %s on line %d
11+
object(SplFixedArray)#1 (1) {
12+
[0]=>
13+
NULL
14+
}

0 commit comments

Comments
 (0)