]> granicus.if.org Git - php/commitdiff
Remove extra pointer in SplFixedArray
authorLevi Morrison <levim@php.net>
Thu, 4 Aug 2016 15:35:14 +0000 (09:35 -0600)
committerNikita Popov <nikic@php.net>
Thu, 11 Aug 2016 16:25:56 +0000 (18:25 +0200)
ext/spl/spl_fixedarray.c
ext/spl/tests/bug62904.phpt

index 1910012b8dc5b2d2d47f7a8119d78505f20d1f1b..741b1dbf14e4bf454d8b3ecee5fa19fc54fee4aa 100644 (file)
@@ -49,7 +49,7 @@ typedef struct _spl_fixedarray { /* {{{ */
 /* }}} */
 
 typedef struct _spl_fixedarray_object { /* {{{ */
-       spl_fixedarray        *array;
+       spl_fixedarray        array;
        zend_function         *fptr_offset_get;
        zend_function         *fptr_offset_set;
        zend_function         *fptr_offset_has;
@@ -148,13 +148,8 @@ static HashTable* spl_fixedarray_object_get_gc(zval *obj, zval **table, int *n)
        spl_fixedarray_object *intern  = Z_SPLFIXEDARRAY_P(obj);
        HashTable *ht = zend_std_get_properties(obj);
 
-       if (intern->array) {
-               *table = intern->array->elements;
-               *n = (int)intern->array->size;
-       } else {
-               *table = NULL;
-               *n = 0;
-       }
+       *table = intern->array.elements;
+       *n = (int)intern->array.size;
 
        return ht;
 }
@@ -166,21 +161,21 @@ static HashTable* spl_fixedarray_object_get_properties(zval *obj) /* {{{{ */
        HashTable *ht = zend_std_get_properties(obj);
        zend_long  i = 0;
 
-       if (intern->array) {
+       if (intern->array.size > 0) {
                zend_long j = zend_hash_num_elements(ht);
 
-               for (i = 0; i < intern->array->size; i++) {
-                       if (!Z_ISUNDEF(intern->array->elements[i])) {
-                               zend_hash_index_update(ht, i, &intern->array->elements[i]);
-                               if (Z_REFCOUNTED(intern->array->elements[i])){
-                                       Z_ADDREF(intern->array->elements[i]);
+               for (i = 0; i < intern->array.size; i++) {
+                       if (!Z_ISUNDEF(intern->array.elements[i])) {
+                               zend_hash_index_update(ht, i, &intern->array.elements[i]);
+                               if (Z_REFCOUNTED(intern->array.elements[i])){
+                                       Z_ADDREF(intern->array.elements[i]);
                                }
                        } else {
                                zend_hash_index_update(ht, i, &EG(uninitialized_zval));
                        }
                }
-               if (j > intern->array->size) {
-                       for (i = intern->array->size; i < j; ++i) {
+               if (j > intern->array.size) {
+                       for (i = intern->array.size; i < j; ++i) {
                                zend_hash_index_del(ht, i);
                        }
                }
@@ -195,15 +190,14 @@ static void spl_fixedarray_object_free_storage(zend_object *object) /* {{{ */
        spl_fixedarray_object *intern = spl_fixed_array_from_obj(object);
        zend_long i;
 
-       if (intern->array) {
-               for (i = 0; i < intern->array->size; i++) {
-                       zval_ptr_dtor(&(intern->array->elements[i]));
+       if (intern->array.size > 0) {
+               for (i = 0; i < intern->array.size; i++) {
+                       zval_ptr_dtor(&(intern->array.elements[i]));
                }
 
-               if (intern->array->size > 0 && intern->array->elements) {
-                       efree(intern->array->elements);
+               if (intern->array.size > 0 && intern->array.elements) {
+                       efree(intern->array.elements);
                }
-               efree(intern->array);
        }
 
        zend_object_std_dtor(&intern->std);
@@ -229,14 +223,8 @@ static zend_object *spl_fixedarray_object_new_ex(zend_class_entry *class_type, z
        if (orig && clone_orig) {
                spl_fixedarray_object *other = Z_SPLFIXEDARRAY_P(orig);
                intern->ce_get_iterator = other->ce_get_iterator;
-               if (!other->array) {
-                       /* leave a empty object, will be dtor later by CLONE handler */
-                       zend_throw_exception(spl_ce_RuntimeException, "The instance wasn't initialized properly", 0);
-               } else {
-                       intern->array = emalloc(sizeof(spl_fixedarray));
-                       spl_fixedarray_init(intern->array, other->array->size);
-                       spl_fixedarray_copy(intern->array, other->array);
-               }
+               spl_fixedarray_init(&intern->array, other->array.size);
+               spl_fixedarray_copy(&intern->array, &other->array);
        }
 
        while (parent) {
@@ -341,13 +329,13 @@ static inline zval *spl_fixedarray_object_read_dimension_helper(spl_fixedarray_o
                index = Z_LVAL_P(offset);
        }
 
-       if (index < 0 || intern->array == NULL || index >= intern->array->size) {
+       if (index < 0 || index >= intern->array.size) {
                zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0);
                return NULL;
-       } else if (Z_ISUNDEF(intern->array->elements[index])) {
+       } else if (Z_ISUNDEF(intern->array.elements[index])) {
                return NULL;
        } else {
-               return &intern->array->elements[index];
+               return &intern->array.elements[index];
        }
 }
 /* }}} */
@@ -394,15 +382,15 @@ static inline void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_o
                index = Z_LVAL_P(offset);
        }
 
-       if (index < 0 || intern->array == NULL || index >= intern->array->size) {
+       if (index < 0 || index >= intern->array.size) {
                zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0);
                return;
        } else {
-               if (!Z_ISUNDEF(intern->array->elements[index])) {
-                       zval_ptr_dtor(&(intern->array->elements[index]));
+               if (!Z_ISUNDEF(intern->array.elements[index])) {
+                       zval_ptr_dtor(&(intern->array.elements[index]));
                }
                ZVAL_DEREF(value);
-               ZVAL_COPY(&intern->array->elements[index], value);
+               ZVAL_COPY(&intern->array.elements[index], value);
        }
 }
 /* }}} */
@@ -442,12 +430,12 @@ static inline void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_o
                index = Z_LVAL_P(offset);
        }
 
-       if (index < 0 || intern->array == NULL || index >= intern->array->size) {
+       if (index < 0 || index >= intern->array.size) {
                zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0);
                return;
        } else {
-               zval_ptr_dtor(&(intern->array->elements[index]));
-               ZVAL_UNDEF(&intern->array->elements[index]);
+               zval_ptr_dtor(&(intern->array.elements[index]));
+               ZVAL_UNDEF(&intern->array.elements[index]);
        }
 }
 /* }}} */
@@ -481,13 +469,13 @@ static inline int spl_fixedarray_object_has_dimension_helper(spl_fixedarray_obje
                index = Z_LVAL_P(offset);
        }
 
-       if (index < 0 || intern->array == NULL || index >= intern->array->size) {
+       if (index < 0 || index >= intern->array.size) {
                retval = 0;
        } else {
-               if (Z_ISUNDEF(intern->array->elements[index])) {
+               if (Z_ISUNDEF(intern->array.elements[index])) {
                        retval = 0;
                } else if (check_empty) {
-                       if (zend_is_true(&intern->array->elements[index])) {
+                       if (zend_is_true(&intern->array.elements[index])) {
                                retval = 1;
                        } else {
                                retval = 0;
@@ -535,14 +523,12 @@ static int spl_fixedarray_object_count_elements(zval *object, zend_long *count)
                if (!Z_ISUNDEF(rv)) {
                        *count = zval_get_long(&rv);
                        zval_ptr_dtor(&rv);
-                       return SUCCESS;
+               } else {
+                       *count = 0;
                }
-       } else if (intern->array) {
-               *count = intern->array->size;
-               return SUCCESS;
+       } else {
+               *count = intern->array.size;
        }
-
-       *count = 0;
        return SUCCESS;
 }
 /* }}} */
@@ -566,13 +552,12 @@ SPL_METHOD(SplFixedArray, __construct)
 
        intern = Z_SPLFIXEDARRAY_P(object);
 
-       if (intern->array) {
+       if (intern->array.size > 0) {
                /* called __construct() twice, bail out */
                return;
        }
 
-       intern->array = emalloc(sizeof(spl_fixedarray));
-       spl_fixedarray_init(intern->array, size);
+       spl_fixedarray_init(&intern->array, size);
 }
 /* }}} */
 
@@ -588,18 +573,17 @@ SPL_METHOD(SplFixedArray, __wakeup)
                return;
        }
 
-       if (!intern->array) {
+       if (intern->array.size == 0) {
                int index = 0;
                int size = zend_hash_num_elements(intern_ht);
 
-               intern->array = emalloc(sizeof(spl_fixedarray));
-               spl_fixedarray_init(intern->array, size);
+               spl_fixedarray_init(&intern->array, size);
 
                ZEND_HASH_FOREACH_VAL(intern_ht, data) {
                        if (Z_REFCOUNTED_P(data)) {
                                Z_ADDREF_P(data);
                        }
-                       ZVAL_COPY_VALUE(&intern->array->elements[index], data);
+                       ZVAL_COPY_VALUE(&intern->array.elements[index], data);
                        index++;
                } ZEND_HASH_FOREACH_END();
 
@@ -622,10 +606,7 @@ SPL_METHOD(SplFixedArray, count)
        }
 
        intern = Z_SPLFIXEDARRAY_P(object);
-       if (intern->array) {
-               RETURN_LONG(intern->array->size);
-       }
-       RETURN_LONG(0);
+       RETURN_LONG(intern->array.size);
 }
 /* }}} */
 
@@ -642,13 +623,13 @@ SPL_METHOD(SplFixedArray, toArray)
        intern = Z_SPLFIXEDARRAY_P(getThis());
 
        array_init(return_value);
-       if (intern->array) {
+       if (intern->array.size > 0) {
                int i = 0;
-               for (; i < intern->array->size; i++) {
-                       if (!Z_ISUNDEF(intern->array->elements[i])) {
-                               zend_hash_index_update(Z_ARRVAL_P(return_value), i, &intern->array->elements[i]);
-                               if (Z_REFCOUNTED(intern->array->elements[i])) {
-                                       Z_ADDREF(intern->array->elements[i]);
+               for (; i < intern->array.size; i++) {
+                       if (!Z_ISUNDEF(intern->array.elements[i])) {
+                               zend_hash_index_update(Z_ARRVAL_P(return_value), i, &intern->array.elements[i]);
+                               if (Z_REFCOUNTED(intern->array.elements[i])) {
+                                       Z_ADDREF(intern->array.elements[i]);
                                }
                        } else {
                                zend_hash_index_update(Z_ARRVAL_P(return_value), i, &EG(uninitialized_zval));
@@ -663,7 +644,7 @@ SPL_METHOD(SplFixedArray, toArray)
 SPL_METHOD(SplFixedArray, fromArray)
 {
        zval *data;
-       spl_fixedarray *array;
+       spl_fixedarray array;
        spl_fixedarray_object *intern;
        int num;
        zend_bool save_indexes = 1;
@@ -672,7 +653,6 @@ SPL_METHOD(SplFixedArray, fromArray)
                return;
        }
 
-       array = ecalloc(1, sizeof(spl_fixedarray));
        num = zend_hash_num_elements(Z_ARRVAL_P(data));
 
        if (num > 0 && save_indexes) {
@@ -683,7 +663,6 @@ SPL_METHOD(SplFixedArray, fromArray)
 
                ZEND_HASH_FOREACH_KEY(Z_ARRVAL_P(data), num_index, str_index) {
                        if (str_index != NULL || (zend_long)num_index < 0) {
-                               efree(array);
                                zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "array must contain only positive integer keys");
                                return;
                        }
@@ -695,30 +674,29 @@ SPL_METHOD(SplFixedArray, fromArray)
 
                tmp = max_index + 1;
                if (tmp <= 0) {
-                       efree(array);
                        zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "integer overflow detected");
                        return;
                }
-               spl_fixedarray_init(array, tmp);
+               spl_fixedarray_init(&array, tmp);
 
                ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(data), num_index, str_index, element) {
                        ZVAL_DEREF(element);
-                       ZVAL_COPY(&array->elements[num_index], element);
+                       ZVAL_COPY(&array.elements[num_index], element);
                } ZEND_HASH_FOREACH_END();
 
        } else if (num > 0 && !save_indexes) {
                zval *element;
                zend_long i = 0;
 
-               spl_fixedarray_init(array, num);
+               spl_fixedarray_init(&array, num);
 
                ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(data), element) {
                        ZVAL_DEREF(element);
-                       ZVAL_COPY(&array->elements[i], element);
+                       ZVAL_COPY(&array.elements[i], element);
                        i++;
                } ZEND_HASH_FOREACH_END();
        } else {
-               spl_fixedarray_init(array, 0);
+               spl_fixedarray_init(&array, 0);
        }
 
        object_init_ex(return_value, spl_ce_SplFixedArray);
@@ -740,10 +718,7 @@ SPL_METHOD(SplFixedArray, getSize)
        }
 
        intern = Z_SPLFIXEDARRAY_P(object);
-       if (intern->array) {
-               RETURN_LONG(intern->array->size);
-       }
-       RETURN_LONG(0);
+       RETURN_LONG(intern->array.size);
 }
 /* }}} */
 
@@ -765,11 +740,8 @@ SPL_METHOD(SplFixedArray, setSize)
        }
 
        intern = Z_SPLFIXEDARRAY_P(object);
-       if (!intern->array) {
-               intern->array = ecalloc(1, sizeof(spl_fixedarray));
-       }
 
-       spl_fixedarray_resize(intern->array, size);
+       spl_fixedarray_resize(&intern->array, size);
        RETURN_TRUE;
 }
 /* }}} */
@@ -873,7 +845,7 @@ static int spl_fixedarray_it_valid(zend_object_iterator *iter) /* {{{ */
                return zend_user_it_valid(iter);
        }
 
-       if (object->current >= 0 && object->array && object->current < object->array->size) {
+       if (object->current >= 0 && object->current < object->array.size) {
                return SUCCESS;
        }
 
@@ -967,7 +939,7 @@ SPL_METHOD(SplFixedArray, valid)
                return;
        }
 
-       RETURN_BOOL(intern->current >= 0 && intern->array && intern->current < intern->array->size);
+       RETURN_BOOL(intern->current >= 0 && intern->current < intern->array.size);
 }
 /* }}} */
 
index 7e392da9abbd7745c592af5c6894cd5e91608ba4..8ce0d7bc7910f2699babd45291b40ffb6d0c0257 100644 (file)
@@ -10,10 +10,9 @@ class foo extends SplFixedArray {
 
 $x = new foo(2);
 
-try {
-    $z = clone $x;
-} catch (Exception $e) {
-    var_dump($e->getMessage());
-}
+$z = clone $x;
+echo "No crash.";
+
 --EXPECTF--
-string(40) "The instance wasn't initialized properly"
+No crash.
+