mike Wed, 26 May 2010 07:24:37 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=299770
Log: Added support for object references in recursive serialize() calls. FR #36424 Bug: http://bugs.php.net/36424 (Assigned) Keeping reference info through recursive calls to serialize() Changed paths: U php/php-src/trunk/NEWS U php/php-src/trunk/ext/spl/spl_array.c U php/php-src/trunk/ext/spl/spl_observer.c U php/php-src/trunk/ext/spl/tests/bug49263.phpt U php/php-src/trunk/ext/standard/basic_functions.h U php/php-src/trunk/ext/standard/php_var.h A php/php-src/trunk/ext/standard/tests/serialize/bug36424.phpt U php/php-src/trunk/ext/standard/var.c U php/php-src/trunk/ext/standard/var_unserializer.c U php/php-src/trunk/ext/standard/var_unserializer.re
Modified: php/php-src/trunk/NEWS =================================================================== --- php/php-src/trunk/NEWS 2010-05-26 06:35:07 UTC (rev 299769) +++ php/php-src/trunk/NEWS 2010-05-26 07:24:37 UTC (rev 299770) @@ -42,6 +42,8 @@ - Added scalar typehinting. (Ilia, Derick) - Added support for JSON_NUMERIC_CHECK option in json_encode() that converts numeric strings to integers. (Ilia) +- Added support for object references in recursive serialize() calls. FR #36424. + (Mike) - default_charset if not specified is now UTF-8 instead of ISO-8859-1. (Rasmus) Modified: php/php-src/trunk/ext/spl/spl_array.c =================================================================== --- php/php-src/trunk/ext/spl/spl_array.c 2010-05-26 06:35:07 UTC (rev 299769) +++ php/php-src/trunk/ext/spl/spl_array.c 2010-05-26 07:24:37 UTC (rev 299770) @@ -59,23 +59,19 @@ #define SPL_ARRAY_CLONE_MASK 0x0300FFFF typedef struct _spl_array_object { - zend_object std; - zval *array; - zval *retval; - HashPosition pos; - ulong pos_h; - int ar_flags; - int is_self; - zend_function *fptr_offset_get; - zend_function *fptr_offset_set; - zend_function *fptr_offset_has; - zend_function *fptr_offset_del; - zend_function *fptr_count; - zend_function *fptr_serialize; - zend_function *fptr_unserialize; - zend_class_entry *ce_get_iterator; - php_serialize_data_t *serialize_data; - php_unserialize_data_t *unserialize_data; + zend_object std; + zval *array; + zval *retval; + HashPosition pos; + ulong pos_h; + int ar_flags; + int is_self; + zend_function *fptr_offset_get; + zend_function *fptr_offset_set; + zend_function *fptr_offset_has; + zend_function *fptr_offset_del; + zend_function *fptr_count; + zend_class_entry* ce_get_iterator; HashTable *debug_info; } spl_array_object; @@ -161,8 +157,6 @@ /* }}} */ zend_object_iterator *spl_array_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC); -int spl_array_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC); -int spl_array_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC); /* {{{ spl_array_object_new_ex */ static zend_object_value spl_array_object_new_ex(zend_class_entry *class_type, spl_array_object **obj, zval *orig, int clone_orig TSRMLS_DC) @@ -182,8 +176,6 @@ object_properties_init(&intern->std, class_type); intern->ar_flags = 0; - intern->serialize_data = NULL; - intern->unserialize_data = NULL; intern->debug_info = NULL; intern->ce_get_iterator = spl_ce_ArrayIterator; if (orig) { @@ -250,14 +242,6 @@ if (intern->fptr_count->common.scope == parent) { intern->fptr_count = NULL; } - zend_hash_find(&class_type->function_table, "serialize", sizeof("serialize"), (void **) &intern->fptr_serialize); - if (intern->fptr_serialize->common.scope == parent) { - intern->fptr_serialize = NULL; - } - zend_hash_find(&class_type->function_table, "unserialize", sizeof("unserialize"), (void **) &intern->fptr_unserialize); - if (intern->fptr_unserialize->common.scope == parent) { - intern->fptr_unserialize = NULL; - } } /* Cache iterator functions if ArrayIterator or derived. Check current's */ /* cache since only current is always required */ @@ -1567,27 +1551,35 @@ } /* }}} */ -smart_str spl_array_serialize_helper(spl_array_object *intern, php_serialize_data_t *var_hash_p TSRMLS_DC) { /* {{{ */ +/* {{{ proto string ArrayObject::serialize() + Serialize the object */ +SPL_METHOD(Array, serialize) +{ + zval *object = getThis(); + spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC); zval members, *pmembers; + php_serialize_data_t var_hash; smart_str buf = {0}; zval *flags; if (!aht) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Array was modified outside object and is no longer an array"); - return buf; + return; } + PHP_VAR_SERIALIZE_INIT(var_hash); + MAKE_STD_ZVAL(flags); ZVAL_LONG(flags, (intern->ar_flags & SPL_ARRAY_CLONE_MASK)); /* storage */ smart_str_appendl(&buf, "x:", 2); - php_var_serialize(&buf, &flags, var_hash_p TSRMLS_CC); + php_var_serialize(&buf, &flags, &var_hash TSRMLS_CC); zval_ptr_dtor(&flags); if (!(intern->ar_flags & SPL_ARRAY_IS_SELF)) { - php_var_serialize(&buf, &intern->array, var_hash_p TSRMLS_CC); + php_var_serialize(&buf, &intern->array, &var_hash TSRMLS_CC); smart_str_appendc(&buf, ';'); } @@ -1600,35 +1592,11 @@ Z_ARRVAL(members) = intern->std.properties; Z_TYPE(members) = IS_ARRAY; pmembers = &members; - php_var_serialize(&buf, &pmembers, var_hash_p TSRMLS_CC); /* finishes the string */ + php_var_serialize(&buf, &pmembers, &var_hash TSRMLS_CC); /* finishes the string */ /* done */ - return buf; -} -/* }}} */ + PHP_VAR_SERIALIZE_DESTROY(var_hash); -/* {{{ proto string ArrayObject::serialize() - Serialize the object */ -SPL_METHOD(Array, serialize) -{ - zval *object = getThis(); - spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); - int was_in_serialize = intern->serialize_data != NULL; - smart_str buf; - - if (!was_in_serialize) { - intern->serialize_data = emalloc(sizeof(php_serialize_data_t)); - PHP_VAR_SERIALIZE_INIT(*intern->serialize_data); - } - - buf = spl_array_serialize_helper(intern, intern->serialize_data TSRMLS_CC); - - if (!was_in_serialize) { - PHP_VAR_SERIALIZE_DESTROY(*intern->serialize_data); - efree(intern->serialize_data); - intern->serialize_data = NULL; - } - if (buf.c) { RETURN_STRINGL(buf.c, buf.len, 0); } @@ -1636,47 +1604,32 @@ RETURN_NULL(); } /* }}} */ -int spl_array_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC) /* {{{ */ +/* {{{ proto void ArrayObject::unserialize(string serialized) + * unserialize the object + */ +SPL_METHOD(Array, unserialize) { - spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (intern->fptr_serialize) { - int retval; - php_serialize_data_t *before; - - before = intern->serialize_data; - intern->serialize_data = (php_serialize_data_t *)data; - - retval = zend_user_serialize(object, buffer, buf_len, data TSRMLS_CC); - - intern->serialize_data = before; - - return retval; - } else { - smart_str buf; - - buf = spl_array_serialize_helper(intern, (php_serialize_data_t *)data TSRMLS_CC); - - if (buf.c) { - *buffer = (unsigned char*)estrndup(buf.c, buf.len); - *buf_len = buf.len; - efree(buf.c); - return SUCCESS; - } else { - return FAILURE; - } - } -} -/* }}} */ - -void spl_array_unserialize_helper(spl_array_object *intern, const unsigned char *buf, int buf_len, php_unserialize_data_t *var_hash_p TSRMLS_DC) /* {{{ */ -{ + char *buf; + int buf_len; const unsigned char *p, *s; + php_unserialize_data_t var_hash; zval *pmembers, *pflags = NULL; long flags; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) { + return; + } + if (buf_len == 0) { + zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Empty serialized string cannot be empty"); + return; + } + /* storage */ - s = p = buf; + s = p = (const unsigned char*)buf; + PHP_VAR_UNSERIALIZE_INIT(var_hash); if (*p!= 'x' || *++p != ':') { goto outexcept; @@ -1684,7 +1637,7 @@ ++p; ALLOC_INIT_ZVAL(pflags); - if (!php_var_unserialize(&pflags, &p, s + buf_len, var_hash_p TSRMLS_CC) || Z_TYPE_P(pflags) != IS_LONG) { + if (!php_var_unserialize(&pflags, &p, s + buf_len, &var_hash TSRMLS_CC) || Z_TYPE_P(pflags) != IS_LONG) { zval_ptr_dtor(&pflags); goto outexcept; } @@ -1710,7 +1663,7 @@ intern->ar_flags |= flags & SPL_ARRAY_CLONE_MASK; zval_ptr_dtor(&intern->array); ALLOC_INIT_ZVAL(intern->array); - if (!php_var_unserialize(&intern->array, &p, s + buf_len, var_hash_p TSRMLS_CC)) { + if (!php_var_unserialize(&intern->array, &p, s + buf_len, &var_hash TSRMLS_CC)) { goto outexcept; } } @@ -1726,7 +1679,7 @@ ++p; ALLOC_INIT_ZVAL(pmembers); - if (!php_var_unserialize(&pmembers, &p, s + buf_len, var_hash_p TSRMLS_CC)) { + if (!php_var_unserialize(&pmembers, &p, s + buf_len, &var_hash TSRMLS_CC)) { zval_ptr_dtor(&pmembers); goto outexcept; } @@ -1739,80 +1692,17 @@ zval_ptr_dtor(&pmembers); /* done reading $serialized */ + + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); return; outexcept: - zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Error at offset %ld of %d bytes", (long)((char*)p - (char *)buf), buf_len); + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len); return; -} -/* }}} */ - -/* {{{ proto void ArrayObject::unserialize(string serialized) - Unserialize the object */ -SPL_METHOD(Array, unserialize) -{ - char *buf; - int buf_len; - spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - int was_in_unserialize = intern->unserialize_data != NULL; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) { - return; - } - - if (buf_len == 0) { - zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Empty serialized string cannot be empty"); - return; - } - - if (!was_in_unserialize) { - intern->unserialize_data = emalloc(sizeof(php_unserialize_data_t)); - PHP_VAR_UNSERIALIZE_INIT(*intern->unserialize_data); - } - - spl_array_unserialize_helper(intern, (const unsigned char *)buf, buf_len, intern->unserialize_data TSRMLS_CC); - - if (!was_in_unserialize) { - PHP_VAR_UNSERIALIZE_DESTROY(*intern->unserialize_data); - efree(intern->unserialize_data); - intern->unserialize_data = NULL; - } } /* }}} */ -int spl_array_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC) -{ - spl_array_object *intern; - - object_init_ex(*object, ce); - intern = (spl_array_object*)zend_object_store_get_object(*object TSRMLS_CC); - - if (intern->fptr_unserialize) { - zval *zdata; - php_unserialize_data_t *before; - MAKE_STD_ZVAL(zdata); - ZVAL_STRINGL(zdata, (char *)buf, buf_len, 1); - - before = intern->unserialize_data; - intern->unserialize_data = (php_unserialize_data_t *)data; - - zend_call_method_with_1_params(object, ce, &ce->unserialize_func, "unserialize", NULL, zdata); - - intern->unserialize_data = before; - - zval_ptr_dtor(&zdata); - } else { - spl_array_unserialize_helper(intern, buf, buf_len, (php_unserialize_data_t *)data TSRMLS_CC); - } - - if (EG(exception)) { - return FAILURE; - } else { - return SUCCESS; - } -} -/* }}} */ - /* {{{ arginfo and function tbale */ ZEND_BEGIN_ARG_INFO(arginfo_array___construct, 0) ZEND_ARG_INFO(0, array) @@ -1928,8 +1818,6 @@ REGISTER_SPL_IMPLEMENTS(ArrayObject, Aggregate); REGISTER_SPL_IMPLEMENTS(ArrayObject, ArrayAccess); REGISTER_SPL_IMPLEMENTS(ArrayObject, Serializable); - spl_ce_ArrayObject->serialize = spl_array_serialize; - spl_ce_ArrayObject->unserialize = spl_array_unserialize; memcpy(&spl_handler_ArrayObject, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); spl_handler_ArrayObject.clone_obj = spl_array_object_clone; @@ -1952,8 +1840,6 @@ REGISTER_SPL_IMPLEMENTS(ArrayIterator, ArrayAccess); REGISTER_SPL_IMPLEMENTS(ArrayIterator, SeekableIterator); REGISTER_SPL_IMPLEMENTS(ArrayIterator, Serializable); - spl_ce_ArrayIterator->serialize = spl_array_serialize; - spl_ce_ArrayIterator->unserialize = spl_array_unserialize; memcpy(&spl_handler_ArrayIterator, &spl_handler_ArrayObject, sizeof(zend_object_handlers)); spl_ce_ArrayIterator->get_iterator = spl_array_get_iterator; Modified: php/php-src/trunk/ext/spl/spl_observer.c =================================================================== --- php/php-src/trunk/ext/spl/spl_observer.c 2010-05-26 06:35:07 UTC (rev 299769) +++ php/php-src/trunk/ext/spl/spl_observer.c 2010-05-26 07:24:37 UTC (rev 299770) @@ -638,7 +638,7 @@ spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); spl_SplObjectStorageElement *element; - zval members, *pmembers; + zval members, *pmembers, *flags; HashPosition pos; php_serialize_data_t var_hash; smart_str buf = {0}; @@ -646,9 +646,11 @@ PHP_VAR_SERIALIZE_INIT(var_hash); /* storage */ - smart_str_appendl(&buf, "x:i:", 4); - smart_str_append_long(&buf, zend_hash_num_elements(&intern->storage)); - smart_str_appendc(&buf, ';'); + smart_str_appendl(&buf, "x:", 2); + MAKE_STD_ZVAL(flags); + ZVAL_LONG(flags, zend_hash_num_elements(&intern->storage)); + php_var_serialize(&buf, &flags, &var_hash TSRMLS_CC); + zval_ptr_dtor(&flags); zend_hash_internal_pointer_reset_ex(&intern->storage, &pos); @@ -716,7 +718,7 @@ ++p; ALLOC_INIT_ZVAL(pcount); - if (!php_var_unserialize(&pcount, &p, s + buf_len, NULL TSRMLS_CC) || Z_TYPE_P(pcount) != IS_LONG) { + if (!php_var_unserialize(&pcount, &p, s + buf_len, &var_hash TSRMLS_CC) || Z_TYPE_P(pcount) != IS_LONG) { zval_ptr_dtor(&pcount); goto outexcept; } Modified: php/php-src/trunk/ext/spl/tests/bug49263.phpt =================================================================== --- php/php-src/trunk/ext/spl/tests/bug49263.phpt 2010-05-26 06:35:07 UTC (rev 299769) +++ php/php-src/trunk/ext/spl/tests/bug49263.phpt 2010-05-26 07:24:37 UTC (rev 299770) @@ -19,7 +19,7 @@ ?> ===DONE=== --EXPECTF-- -C:16:"SplObjectStorage":113:{x:i:2;O:8:"stdClass":0:{},a:2:{s:4:"prev";i:2;s:4:"next";O:8:"stdClass":0:{}};r:4;,a:1:{s:4:"prev";r:1;};m:a:0:{}} +C:16:"SplObjectStorage":113:{x:i:2;O:8:"stdClass":0:{},a:2:{s:4:"prev";i:2;s:4:"next";O:8:"stdClass":0:{}};r:6;,a:1:{s:4:"prev";r:3;};m:a:0:{}} object(SplObjectStorage)#2 (1) { ["storage":"SplObjectStorage":private]=> array(2) { Modified: php/php-src/trunk/ext/standard/basic_functions.h =================================================================== --- php/php-src/trunk/ext/standard/basic_functions.h 2010-05-26 06:35:07 UTC (rev 299769) +++ php/php-src/trunk/ext/standard/basic_functions.h 2010-05-26 07:24:37 UTC (rev 299770) @@ -201,6 +201,14 @@ /* var.c */ zend_class_entry *incomplete_class; + struct { + void *var_hash; + unsigned level; + } serialize; + struct { + void *var_hash; + unsigned level; + } unserialize; /* url_scanner_ex.re */ url_adapt_state_ex_t url_adapt_state_ex; Modified: php/php-src/trunk/ext/standard/php_var.h =================================================================== --- php/php-src/trunk/ext/standard/php_var.h 2010-05-26 06:35:07 UTC (rev 299769) +++ php/php-src/trunk/ext/standard/php_var.h 2010-05-26 07:24:37 UTC (rev 299770) @@ -21,6 +21,7 @@ #ifndef PHP_VAR_H #define PHP_VAR_H +#include "ext/standard/basic_functions.h" #include "ext/standard/php_smart_str_public.h" PHP_FUNCTION(var_dump); @@ -35,30 +36,69 @@ PHPAPI void php_var_export(zval **struc, int level TSRMLS_DC); PHPAPI void php_debug_zval_dump(zval **struc, int level TSRMLS_DC); -/* typdef HashTable php_serialize_data_t; */ -#define php_serialize_data_t HashTable +typedef HashTable* php_serialize_data_t; struct php_unserialize_data { void *first; void *first_dtor; }; -typedef struct php_unserialize_data php_unserialize_data_t; +typedef struct php_unserialize_data* php_unserialize_data_t; PHPAPI void php_var_serialize(smart_str *buf, zval **struc, php_serialize_data_t *var_hash TSRMLS_DC); PHPAPI int php_var_unserialize(zval **rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC); -#define PHP_VAR_SERIALIZE_INIT(var_hash) \ - zend_hash_init(&(var_hash), 10, NULL, NULL, 0) -#define PHP_VAR_SERIALIZE_DESTROY(var_hash) \ - zend_hash_destroy(&(var_hash)) +#define PHP_VAR_SERIALIZE_INIT(var_hash_ptr) \ +do { \ + if (BG(serialize).level) { \ + (var_hash_ptr) = BG(serialize).var_hash; \ + ++BG(serialize).level; \ + } else { \ + ALLOC_HASHTABLE(var_hash_ptr); \ + zend_hash_init((var_hash_ptr), 10, NULL, NULL, 0); \ + BG(serialize).var_hash = (var_hash_ptr); \ + BG(serialize).level = 1; \ + } \ +} while(0) -#define PHP_VAR_UNSERIALIZE_INIT(var_hash) \ - (var_hash).first = 0; \ - (var_hash).first_dtor = 0 -#define PHP_VAR_UNSERIALIZE_DESTROY(var_hash) \ - var_destroy(&(var_hash)) +#define PHP_VAR_SERIALIZE_DESTROY(var_hash_ptr) \ +do { \ + if (BG(serialize).level) { \ + if (!--BG(serialize).level) { \ + zend_hash_destroy(BG(serialize).var_hash); \ + FREE_HASHTABLE(BG(serialize).var_hash); \ + BG(serialize).var_hash = NULL; \ + } \ + } else { \ + zend_hash_destroy((var_hash_ptr)); \ + } \ +} while (0) +#define PHP_VAR_UNSERIALIZE_INIT(var_hash_ptr) \ +do { \ + if (BG(unserialize).level) { \ + (var_hash_ptr) = BG(unserialize).var_hash; \ + ++BG(unserialize).level; \ + } else { \ + (var_hash_ptr) = ecalloc(1, sizeof(struct php_unserialize_data)); \ + BG(unserialize).var_hash = (var_hash_ptr); \ + BG(unserialize).level = 1; \ + } \ +} while (0) + +#define PHP_VAR_UNSERIALIZE_DESTROY(var_hash_ptr) \ +do { \ + if (BG(unserialize).level) { \ + if (!--BG(unserialize).level) { \ + var_destroy(&(var_hash_ptr)); \ + efree((var_hash_ptr)); \ + BG(unserialize).var_hash = NULL; \ + } \ + } else { \ + var_destroy(&(var_hash_ptr)); \ + } \ +} while (0) + PHPAPI void var_replace(php_unserialize_data_t *var_hash, zval *ozval, zval **nzval); PHPAPI void var_destroy(php_unserialize_data_t *var_hash); Added: php/php-src/trunk/ext/standard/tests/serialize/bug36424.phpt =================================================================== --- php/php-src/trunk/ext/standard/tests/serialize/bug36424.phpt (rev 0) +++ php/php-src/trunk/ext/standard/tests/serialize/bug36424.phpt 2010-05-26 07:24:37 UTC (rev 299770) @@ -0,0 +1,72 @@ +--TEST-- +Bug #36424 - Serializable interface breaks object references +--FILE-- +<?php + +echo "-TEST\n"; + +class a implements Serializable { + function serialize() { + return serialize(get_object_vars($this)); + } + function unserialize($s) { + foreach (unserialize($s) as $p=>$v) { + $this->$p=$v; + } + } +} +class b extends a {} +class c extends b {} + +$c = new c; +$c->a = new a; +$c->a->b = new b; +$c->a->b->c = $c; +$c->a->c = $c; +$c->a->b->a = $c->a; +$c->a->a = $c->a; + +$s = serialize($c); +printf("%s\n", $s); + +$d = unserialize($s); + +var_dump( + $d === $d->a->b->c, + $d->a->a === $d->a, + $d->a->b->a === $d->a, + $d->a->c === $d +); + +print_r($d); + +echo "Done\n"; + +?> +--EXPECTF-- +%aTEST +C:1:"c":108:{a:1:{s:1:"a";C:1:"a":81:{a:3:{s:1:"b";C:1:"b":30:{a:2:{s:1:"c";r:1;s:1:"a";r:3;}}s:1:"c";r:1;s:1:"a";r:3;}}}} +bool(true) +bool(true) +bool(true) +bool(true) +c Object +( + [a] => a Object + ( + [b] => b Object + ( + [c] => c Object + *RECURSION* + [a] => a Object + *RECURSION* + ) + + [c] => c Object + *RECURSION* + [a] => a Object + *RECURSION* + ) + +) +Done Modified: php/php-src/trunk/ext/standard/var.c =================================================================== --- php/php-src/trunk/ext/standard/var.c 2010-05-26 06:35:07 UTC (rev 299769) +++ php/php-src/trunk/ext/standard/var.c 2010-05-26 07:24:37 UTC (rev 299770) @@ -498,12 +498,18 @@ var_no = -1; zend_hash_next_index_insert(var_hash, &var_no, sizeof(var_no), NULL); } +#if 0 + fprintf(stderr, "- had var (%d): %lu\n", Z_TYPE_P(var), **(ulong**)var_old); +#endif return FAILURE; } /* +1 because otherwise hash will think we are trying to store NULL pointer */ var_no = zend_hash_num_elements(var_hash) + 1; zend_hash_add(var_hash, p, len, &var_no, sizeof(var_no), NULL); +#if 0 + fprintf(stderr, "+ add var (%d): %lu\n", Z_TYPE_P(var), var_no); +#endif return SUCCESS; } /* }}} */ @@ -814,9 +820,9 @@ } /* }}} */ -PHPAPI void php_var_serialize(smart_str *buf, zval **struc, HashTable *var_hash TSRMLS_DC) /* {{{ */ +PHPAPI void php_var_serialize(smart_str *buf, zval **struc, php_serialize_data_t *var_hash TSRMLS_DC) /* {{{ */ { - php_var_serialize_intern(buf, *struc, var_hash TSRMLS_CC); + php_var_serialize_intern(buf, *struc, *var_hash TSRMLS_CC); smart_str_0(buf); } /* }}} */ Modified: php/php-src/trunk/ext/standard/var_unserializer.c =================================================================== --- php/php-src/trunk/ext/standard/var_unserializer.c 2010-05-26 06:35:07 UTC (rev 299769) +++ php/php-src/trunk/ext/standard/var_unserializer.c 2010-05-26 07:24:37 UTC (rev 299770) @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.5 on Mon Apr 12 10:11:22 2010 */ +/* Generated by re2c 0.13.5 on Wed May 26 09:11:18 2010 */ #line 1 "ext/standard/var_unserializer.re" /* +----------------------------------------------------------------------+ @@ -35,8 +35,11 @@ static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval) { - var_entries *var_hash = var_hashx->first, *prev = NULL; - + var_entries *var_hash = (*var_hashx)->first, *prev = NULL; +#if 0 + fprintf(stderr, "var_push(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); +#endif + while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) { prev = var_hash; var_hash = var_hash->next; @@ -47,8 +50,8 @@ var_hash->used_slots = 0; var_hash->next = 0; - if (!var_hashx->first) - var_hashx->first = var_hash; + if (!(*var_hashx)->first) + (*var_hashx)->first = var_hash; else prev->next = var_hash; } @@ -58,8 +61,11 @@ static inline void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval) { - var_entries *var_hash = var_hashx->first_dtor, *prev = NULL; - + var_entries *var_hash = (*var_hashx)->first_dtor, *prev = NULL; +#if 0 + fprintf(stderr, "var_push_dtor(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); +#endif + while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) { prev = var_hash; var_hash = var_hash->next; @@ -70,8 +76,8 @@ var_hash->used_slots = 0; var_hash->next = 0; - if (!var_hashx->first_dtor) - var_hashx->first_dtor = var_hash; + if (!(*var_hashx)->first_dtor) + (*var_hashx)->first_dtor = var_hash; else prev->next = var_hash; } @@ -83,7 +89,10 @@ PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval) { long i; - var_entries *var_hash = var_hashx->first; + var_entries *var_hash = (*var_hashx)->first; +#if 0 + fprintf(stderr, "var_replace(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(nzval)); +#endif while (var_hash) { for (i = 0; i < var_hash->used_slots; i++) { @@ -98,8 +107,11 @@ static int var_access(php_unserialize_data_t *var_hashx, long id, zval ***store) { - var_entries *var_hash = var_hashx->first; - + var_entries *var_hash = (*var_hashx)->first; +#if 0 + fprintf(stderr, "var_access(%ld): %ld\n", var_hash?var_hash->used_slots:-1L, id); +#endif + while (id >= VAR_ENTRIES_MAX && var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) { var_hash = var_hash->next; id -= VAR_ENTRIES_MAX; @@ -118,7 +130,10 @@ { void *next; long i; - var_entries *var_hash = var_hashx->first; + var_entries *var_hash = (*var_hashx)->first; +#if 0 + fprintf(stderr, "var_destroy(%ld)\n", var_hash?var_hash->used_slots:-1L); +#endif while (var_hash) { next = var_hash->next; @@ -126,7 +141,7 @@ var_hash = next; } - var_hash = var_hashx->first_dtor; + var_hash = (*var_hashx)->first_dtor; while (var_hash) { for (i = 0; i < var_hash->used_slots; i++) { @@ -190,7 +205,7 @@ #define YYMARKER marker -#line 198 "ext/standard/var_unserializer.re" +#line 213 "ext/standard/var_unserializer.re" @@ -396,7 +411,7 @@ -#line 400 "ext/standard/var_unserializer.c" +#line 415 "ext/standard/var_unserializer.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -456,9 +471,9 @@ yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy95; yy3: -#line 722 "ext/standard/var_unserializer.re" +#line 737 "ext/standard/var_unserializer.re" { return 0; } -#line 462 "ext/standard/var_unserializer.c" +#line 477 "ext/standard/var_unserializer.c" yy4: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy89; @@ -501,13 +516,13 @@ goto yy3; yy14: ++YYCURSOR; -#line 716 "ext/standard/var_unserializer.re" +#line 731 "ext/standard/var_unserializer.re" { /* this is the case where we have less data than planned */ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data"); return 0; /* not sure if it should be 0 or 1 here? */ } -#line 511 "ext/standard/var_unserializer.c" +#line 526 "ext/standard/var_unserializer.c" yy16: yych = *++YYCURSOR; goto yy3; @@ -537,7 +552,7 @@ yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 599 "ext/standard/var_unserializer.re" +#line 614 "ext/standard/var_unserializer.re" { size_t len, len2, len3, maxlen; long elements; @@ -654,7 +669,7 @@ return object_common2(UNSERIALIZE_PASSTHRU, elements); } -#line 658 "ext/standard/var_unserializer.c" +#line 673 "ext/standard/var_unserializer.c" yy25: yych = *++YYCURSOR; if (yych <= ',') { @@ -679,7 +694,7 @@ yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 591 "ext/standard/var_unserializer.re" +#line 606 "ext/standard/var_unserializer.re" { INIT_PZVAL(*rval); @@ -687,7 +702,7 @@ return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } -#line 691 "ext/standard/var_unserializer.c" +#line 706 "ext/standard/var_unserializer.c" yy32: yych = *++YYCURSOR; if (yych == '+') goto yy33; @@ -708,7 +723,7 @@ yych = *++YYCURSOR; if (yych != '{') goto yy18; ++YYCURSOR; -#line 571 "ext/standard/var_unserializer.re" +#line 586 "ext/standard/var_unserializer.re" { long elements = parse_iv(start + 2); /* use iv() not uiv() in order to check data range */ @@ -728,7 +743,7 @@ return finish_nested_data(UNSERIALIZE_PASSTHRU); } -#line 732 "ext/standard/var_unserializer.c" +#line 747 "ext/standard/var_unserializer.c" yy39: yych = *++YYCURSOR; if (yych == '+') goto yy40; @@ -749,7 +764,7 @@ yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 542 "ext/standard/var_unserializer.re" +#line 557 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; @@ -778,7 +793,7 @@ ZVAL_STRINGL(*rval, str, len, 0); return 1; } -#line 782 "ext/standard/var_unserializer.c" +#line 797 "ext/standard/var_unserializer.c" yy46: yych = *++YYCURSOR; if (yych == '+') goto yy47; @@ -799,7 +814,7 @@ yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 514 "ext/standard/var_unserializer.re" +#line 529 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; @@ -827,7 +842,7 @@ ZVAL_STRINGL(*rval, str, len, 1); return 1; } -#line 831 "ext/standard/var_unserializer.c" +#line 846 "ext/standard/var_unserializer.c" yy53: yych = *++YYCURSOR; if (yych <= '/') { @@ -915,7 +930,7 @@ } yy63: ++YYCURSOR; -#line 504 "ext/standard/var_unserializer.re" +#line 519 "ext/standard/var_unserializer.re" { #if SIZEOF_LONG == 4 use_double: @@ -925,7 +940,7 @@ ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL)); return 1; } -#line 929 "ext/standard/var_unserializer.c" +#line 944 "ext/standard/var_unserializer.c" yy65: yych = *++YYCURSOR; if (yych <= ',') { @@ -984,7 +999,7 @@ yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; -#line 489 "ext/standard/var_unserializer.re" +#line 504 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); @@ -999,7 +1014,7 @@ return 1; } -#line 1003 "ext/standard/var_unserializer.c" +#line 1018 "ext/standard/var_unserializer.c" yy76: yych = *++YYCURSOR; if (yych == 'N') goto yy73; @@ -1026,7 +1041,7 @@ if (yych <= '9') goto yy79; if (yych != ';') goto yy18; ++YYCURSOR; -#line 462 "ext/standard/var_unserializer.re" +#line 477 "ext/standard/var_unserializer.re" { #if SIZEOF_LONG == 4 int digits = YYCURSOR - start - 3; @@ -1053,7 +1068,7 @@ ZVAL_LONG(*rval, parse_iv(start + 2)); return 1; } -#line 1057 "ext/standard/var_unserializer.c" +#line 1072 "ext/standard/var_unserializer.c" yy83: yych = *++YYCURSOR; if (yych <= '/') goto yy18; @@ -1061,24 +1076,24 @@ yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; -#line 455 "ext/standard/var_unserializer.re" +#line 470 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_BOOL(*rval, parse_iv(start + 2)); return 1; } -#line 1072 "ext/standard/var_unserializer.c" +#line 1087 "ext/standard/var_unserializer.c" yy87: ++YYCURSOR; -#line 448 "ext/standard/var_unserializer.re" +#line 463 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_NULL(*rval); return 1; } -#line 1082 "ext/standard/var_unserializer.c" +#line 1097 "ext/standard/var_unserializer.c" yy89: yych = *++YYCURSOR; if (yych <= ',') { @@ -1101,7 +1116,7 @@ if (yych <= '9') goto yy91; if (yych != ';') goto yy18; ++YYCURSOR; -#line 425 "ext/standard/var_unserializer.re" +#line 440 "ext/standard/var_unserializer.re" { long id; @@ -1124,7 +1139,7 @@ return 1; } -#line 1128 "ext/standard/var_unserializer.c" +#line 1143 "ext/standard/var_unserializer.c" yy95: yych = *++YYCURSOR; if (yych <= ',') { @@ -1147,7 +1162,7 @@ if (yych <= '9') goto yy97; if (yych != ';') goto yy18; ++YYCURSOR; -#line 404 "ext/standard/var_unserializer.re" +#line 419 "ext/standard/var_unserializer.re" { long id; @@ -1168,9 +1183,9 @@ return 1; } -#line 1172 "ext/standard/var_unserializer.c" +#line 1187 "ext/standard/var_unserializer.c" } -#line 724 "ext/standard/var_unserializer.re" +#line 739 "ext/standard/var_unserializer.re" return 0; Modified: php/php-src/trunk/ext/standard/var_unserializer.re =================================================================== --- php/php-src/trunk/ext/standard/var_unserializer.re 2010-05-26 06:35:07 UTC (rev 299769) +++ php/php-src/trunk/ext/standard/var_unserializer.re 2010-05-26 07:24:37 UTC (rev 299770) @@ -33,8 +33,11 @@ static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval) { - var_entries *var_hash = var_hashx->first, *prev = NULL; - + var_entries *var_hash = (*var_hashx)->first, *prev = NULL; +#if 0 + fprintf(stderr, "var_push(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); +#endif + while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) { prev = var_hash; var_hash = var_hash->next; @@ -45,8 +48,8 @@ var_hash->used_slots = 0; var_hash->next = 0; - if (!var_hashx->first) - var_hashx->first = var_hash; + if (!(*var_hashx)->first) + (*var_hashx)->first = var_hash; else prev->next = var_hash; } @@ -56,8 +59,11 @@ static inline void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval) { - var_entries *var_hash = var_hashx->first_dtor, *prev = NULL; - + var_entries *var_hash = (*var_hashx)->first_dtor, *prev = NULL; +#if 0 + fprintf(stderr, "var_push_dtor(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); +#endif + while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) { prev = var_hash; var_hash = var_hash->next; @@ -68,8 +74,8 @@ var_hash->used_slots = 0; var_hash->next = 0; - if (!var_hashx->first_dtor) - var_hashx->first_dtor = var_hash; + if (!(*var_hashx)->first_dtor) + (*var_hashx)->first_dtor = var_hash; else prev->next = var_hash; } @@ -81,7 +87,10 @@ PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval) { long i; - var_entries *var_hash = var_hashx->first; + var_entries *var_hash = (*var_hashx)->first; +#if 0 + fprintf(stderr, "var_replace(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(nzval)); +#endif while (var_hash) { for (i = 0; i < var_hash->used_slots; i++) { @@ -96,8 +105,11 @@ static int var_access(php_unserialize_data_t *var_hashx, long id, zval ***store) { - var_entries *var_hash = var_hashx->first; - + var_entries *var_hash = (*var_hashx)->first; +#if 0 + fprintf(stderr, "var_access(%ld): %ld\n", var_hash?var_hash->used_slots:-1L, id); +#endif + while (id >= VAR_ENTRIES_MAX && var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) { var_hash = var_hash->next; id -= VAR_ENTRIES_MAX; @@ -116,7 +128,10 @@ { void *next; long i; - var_entries *var_hash = var_hashx->first; + var_entries *var_hash = (*var_hashx)->first; +#if 0 + fprintf(stderr, "var_destroy(%ld)\n", var_hash?var_hash->used_slots:-1L); +#endif while (var_hash) { next = var_hash->next; @@ -124,7 +139,7 @@ var_hash = next; } - var_hash = var_hashx->first_dtor; + var_hash = (*var_hashx)->first_dtor; while (var_hash) { for (i = 0; i < var_hash->used_slots; i++) {
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php