]> granicus.if.org Git - php/commitdiff
Little improvement, update NEWs, added test
authorXinchen Hui <laruence@php.net>
Fri, 13 Mar 2015 16:52:53 +0000 (00:52 +0800)
committerXinchen Hui <laruence@php.net>
Fri, 13 Mar 2015 16:52:53 +0000 (00:52 +0800)
NEWS
ext/spl/spl_observer.c
ext/spl/tests/bug69227.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 39e404f57749d885745cd9079e111ba0fa8e4261..5e1a68a44cf8ed00ea607c4a99c075ca20df98f7 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,10 @@ PHP                                                                        NEWS
    . Fixed bug #68846 (False detection of CJK Unified Ideographs Extension E).
     (Masaki Kagaya)
 
+- SPL:
+   . Fixed #69227 (Use after free in zval_scan caused by
+     spl_object_storage_get_gc). (adam dot scarr at 99designs dot com)
+
 19 Mar 2015, PHP 5.5.23
 
 - Core:
index 2b50319a62933bdf55015a1b65c9b9ffbc5b5b6a..733257f817b8566dd55b7d6fca5ed4e3a18cf8f9 100644 (file)
@@ -87,7 +87,7 @@ typedef struct _spl_SplObjectStorage { /* {{{ */
        zend_function    *fptr_get_hash;
        HashTable        *debug_info;
        zval            **gcdata;
-       long              gcdata_len;
+       long              gcdata_num;
 } spl_SplObjectStorage; /* }}} */
 
 /* {{{ storage is an assoc aray of [zend_object_value]=>[zval *obj, zval *inf] */
@@ -269,9 +269,6 @@ static zend_object_value spl_object_storage_new_ex(zend_class_entry *class_type,
        zend_object_std_init(&intern->std, class_type TSRMLS_CC);
        object_properties_init(&intern->std, class_type);
 
-       intern->gcdata = NULL;
-       intern->gcdata_len = 0;
-
        zend_hash_init(&intern->storage, 0, NULL, (void (*)(void *))spl_object_storage_dtor, 0);
 
        retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_SplOjectStorage_free_storage, NULL TSRMLS_CC);
@@ -371,15 +368,14 @@ static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_D
 /* overriden for garbage collection */
 static HashTable *spl_object_storage_get_gc(zval *obj, zval ***table, int *n TSRMLS_DC) /* {{{ */
 {
+       long i = 0;
        spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC);
        spl_SplObjectStorageElement *element;
        HashPosition pos;
-       long i = 0;
-       long requiredLength = intern->storage.nNumOfElements * 2;
 
-       if (requiredLength > intern->gcdata_len) {
-               intern->gcdata = (zval**)erealloc(intern->gcdata, sizeof(zval*) * requiredLength);
-               intern->gcdata_len = requiredLength;
+       if (intern->storage.nNumOfElements > intern->gcdata_num) {
+               intern->gcdata_num = intern->storage.nNumOfElements * 2;
+               intern->gcdata = (zval**)erealloc(intern->gcdata, sizeof(zval*) * intern->gcdata_num);
        }
 
        zend_hash_internal_pointer_reset_ex(&intern->storage, &pos);
diff --git a/ext/spl/tests/bug69227.phpt b/ext/spl/tests/bug69227.phpt
new file mode 100644 (file)
index 0000000..812d8ba
--- /dev/null
@@ -0,0 +1,14 @@
+--TEST--
+Bug #69227 (Use after free in zval_scan caused by spl_object_storage_get_gc)
+--INI--
+zend.enable_gc=1
+--FILE--
+<?php
+
+$s = new SplObjectStorage();
+$s->attach($s);
+gc_collect_cycles();
+echo "ok";
+?>
+--EXPECT--
+ok