From: Xinchen Hui Date: Fri, 13 Mar 2015 17:01:02 +0000 (+0800) Subject: Merge branch 'PHP-5.6' X-Git-Tag: PRE_PHP7_NSAPI_REMOVAL~669 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e827d1a424adf7238dbd43154f9ff938592bdce7;p=php Merge branch 'PHP-5.6' Conflicts: ext/spl/spl_observer.c --- e827d1a424adf7238dbd43154f9ff938592bdce7 diff --cc ext/spl/spl_observer.c index ae35f8aec2,56d1a16ac0..e727b9e493 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@@ -80,13 -80,15 +80,15 @@@ PHPAPI zend_class_entry *spl_ce_Mul PHPAPI zend_object_handlers spl_handler_SplObjectStorage; typedef struct _spl_SplObjectStorage { /* {{{ */ - zend_object std; HashTable storage; - long index; + zend_long index; HashPosition pos; - long flags; + zend_long flags; zend_function *fptr_get_hash; HashTable *debug_info; - zval **gcdata; - long gcdata_num; ++ zval *gcdata; ++ size_t gcdata_num; + zend_object std; } spl_SplObjectStorage; /* }}} */ /* {{{ storage is an assoc aray of [zend_object_value]=>[zval *obj, zval *inf] */ @@@ -114,17 -109,32 +116,22 @@@ void spl_SplObjectStorage_free_storage( zend_hash_destroy(intern->debug_info); efree(intern->debug_info); } + + if (intern->gcdata != NULL) { + efree(intern->gcdata); + } + - efree(object); } /* }}} */ -static char *spl_object_storage_get_hash(spl_SplObjectStorage *intern, zval *this, zval *obj, int *hash_len_ptr TSRMLS_DC) { +static zend_string *spl_object_storage_get_hash(spl_SplObjectStorage *intern, zval *this, zval *obj) { if (intern->fptr_get_hash) { - zval *rv; - zend_call_method_with_1_params(&this, intern->std.ce, &intern->fptr_get_hash, "getHash", &rv, obj); - if (rv) { - if (Z_TYPE_P(rv) == IS_STRING) { - int hash_len = Z_STRLEN_P(rv); - char *hash = emalloc((hash_len+1)*sizeof(char)); - strncpy(hash, Z_STRVAL_P(rv), hash_len); - hash[hash_len] = 0; - - zval_ptr_dtor(&rv); - if (hash_len_ptr) { - *hash_len_ptr = hash_len; - } - return hash; + zval rv; + zend_call_method_with_1_params(this, intern->std.ce, &intern->fptr_get_hash, "getHash", &rv, obj); + if (!Z_ISUNDEF(rv)) { + if (Z_TYPE(rv) == IS_STRING) { + return Z_STR(rv); } else { - zend_throw_exception(spl_ce_RuntimeException, "Hash needs to be a string", 0 TSRMLS_CC); + zend_throw_exception(spl_ce_RuntimeException, "Hash needs to be a string", 0); zval_ptr_dtor(&rv); return NULL; @@@ -350,41 -366,30 +356,27 @@@ static HashTable* spl_object_storage_de } /* }}} */ - /* overriden for garbage collection - * This is very hacky */ + /* overriden for garbage collection */ -static HashTable *spl_object_storage_get_gc(zval *obj, zval ***table, int *n TSRMLS_DC) /* {{{ */ +static HashTable *spl_object_storage_get_gc(zval *obj, zval **table, int *n) /* {{{ */ { - long i = 0; - spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC); ++ int i = 0; + spl_SplObjectStorage *intern = Z_SPLOBJSTORAGE_P(obj); spl_SplObjectStorageElement *element; - HashTable *props; - zval *gcdata_arr, tmp; - - props = std_object_handlers.get_properties(obj); - - *table = NULL; - *n = 0; - HashPosition pos; - /* clean \x00gcdata, as it may be out of date */ - if ((gcdata_arr = zend_hash_str_find(props, "\x00gcdata", sizeof("\x00gcdata") - 1)) != NULL) { - zend_hash_clean(Z_ARRVAL_P(gcdata_arr)); - } - - if (gcdata_arr == NULL) { - array_init(&tmp); - /* don't decrease refcount of members when destroying */ - Z_ARRVAL_P(&tmp)->pDestructor = NULL; - - /* name starts with \x00 to make tampering in user-land more difficult */ - zend_hash_str_add(props, "\x00gcdata", sizeof("\x00gcdata") - 1, &tmp); - gcdata_arr = &tmp; + 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); ++ intern->gcdata = (zval*)erealloc(intern->gcdata, sizeof(zval) * intern->gcdata_num); } - zend_hash_internal_pointer_reset_ex(&intern->storage, &pos); - while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) { - intern->gcdata[i++] = element->obj; - intern->gcdata[i++] = element->inf; - zend_hash_move_forward_ex(&intern->storage, &pos); - } + ZEND_HASH_FOREACH_PTR(&intern->storage, element) { - add_next_index_zval(gcdata_arr, &element->obj); - add_next_index_zval(gcdata_arr, &element->inf); ++ ZVAL_COPY_VALUE(&intern->gcdata[i++], &element->obj); ++ ZVAL_COPY_VALUE(&intern->gcdata[i++], &element->inf); + } ZEND_HASH_FOREACH_END(); - return props; + *table = intern->gcdata; + *n = i; + + return std_object_handlers.get_properties(obj TSRMLS_CC); } /* }}} */ @@@ -769,10 -785,12 +761,10 @@@ SPL_METHOD(SplObjectStorage, serialize /* members */ smart_str_appendl(&buf, "m:", 2); - INIT_PZVAL(&members); - Z_ARRVAL(members) = zend_std_get_properties(getThis() TSRMLS_CC); - Z_TYPE(members) = IS_ARRAY; + - pmembers = &members; - php_var_serialize(&buf, &pmembers, &var_hash TSRMLS_CC); /* finishes the string */ + ZVAL_ARR(&members, zend_array_dup(zend_std_get_properties(getThis()))); - zend_hash_str_del(Z_ARRVAL(members), "\x00gcdata", sizeof("\x00gcdata") - 1); + php_var_serialize(&buf, &members, &var_hash); /* finishes the string */ + zval_ptr_dtor(&members); /* done */ PHP_VAR_SERIALIZE_DESTROY(var_hash);