mike Wed, 19 Oct 2011 10:09:24 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=318210
Log: Fix Bug #55801 Behavior of unserialize has changed: (un)serialize in __wakeup/__sleep now use clean var_hashes Bug: https://bugs.php.net/55801 (Feedback) Behavior of unserialize has changed Changed paths: U php/php-src/branches/PHP_5_4/ext/standard/basic_functions.h U php/php-src/branches/PHP_5_4/ext/standard/php_var.h U php/php-src/branches/PHP_5_4/ext/standard/var.c U php/php-src/branches/PHP_5_4/ext/standard/var_unserializer.re U php/php-src/trunk/ext/standard/basic_functions.h U php/php-src/trunk/ext/standard/php_var.h U php/php-src/trunk/ext/standard/var.c U php/php-src/trunk/ext/standard/var_unserializer.re
Modified: php/php-src/branches/PHP_5_4/ext/standard/basic_functions.h =================================================================== --- php/php-src/branches/PHP_5_4/ext/standard/basic_functions.h 2011-10-19 07:04:34 UTC (rev 318209) +++ php/php-src/branches/PHP_5_4/ext/standard/basic_functions.h 2011-10-19 10:09:24 UTC (rev 318210) @@ -204,6 +204,7 @@ /* var.c */ zend_class_entry *incomplete_class; + unsigned serialize_lock; /* whether to use the locally supplied var_hash instead (__sleep/__wakeup) */ struct { void *var_hash; unsigned level; Modified: php/php-src/branches/PHP_5_4/ext/standard/php_var.h =================================================================== --- php/php-src/branches/PHP_5_4/ext/standard/php_var.h 2011-10-19 07:04:34 UTC (rev 318209) +++ php/php-src/branches/PHP_5_4/ext/standard/php_var.h 2011-10-19 10:09:24 UTC (rev 318210) @@ -12,7 +12,7 @@ | obtain it through the world-wide-web, please send a note to | | lice...@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Author: Jani Lehtimäki <j...@njet.net> | + | Author: Jani Lehtimäki <j...@njet.net> | +----------------------------------------------------------------------+ */ @@ -54,52 +54,62 @@ #define PHP_VAR_SERIALIZE_INIT(var_hash_ptr) \ do { \ - if (BG(serialize).level) { \ + /* fprintf(stderr, "SERIALIZE_INIT == lock: %u, level: %u\n", BG(serialize_lock), BG(serialize).level); */ \ + if (BG(serialize_lock) || !BG(serialize).level) { \ + ALLOC_HASHTABLE(var_hash_ptr); \ + zend_hash_init((var_hash_ptr), 10, NULL, NULL, 0); \ + if (!BG(serialize_lock)) { \ + BG(serialize).var_hash = (var_hash_ptr); \ + BG(serialize).level = 1; \ + } \ + } else { \ (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_SERIALIZE_DESTROY(var_hash_ptr) \ do { \ - if (BG(serialize).level) { \ + /* fprintf(stderr, "SERIALIZE_DESTROY == lock: %u, level: %u\n", BG(serialize_lock), BG(serialize).level); */ \ + if (BG(serialize_lock) || !BG(serialize).level) { \ + zend_hash_destroy((var_hash_ptr)); \ + FREE_HASHTABLE(var_hash_ptr); \ + } else { \ 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) { \ + /* fprintf(stderr, "UNSERIALIZE_INIT == lock: %u, level: %u\n", BG(serialize_lock), BG(unserialize).level); */ \ + if (BG(serialize_lock) || !BG(unserialize).level) { \ + (var_hash_ptr) = ecalloc(1, sizeof(struct php_unserialize_data)); \ + if (!BG(serialize_lock)) { \ + BG(unserialize).var_hash = (var_hash_ptr); \ + BG(unserialize).level = 1; \ + } \ + } else { \ (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) { \ + /* fprintf(stderr, "UNSERIALIZE_DESTROY == lock: %u, level: %u\n", BG(serialize_lock), BG(unserialize).level); */ \ + if (BG(serialize_lock) || !BG(unserialize).level) { \ + var_destroy(&(var_hash_ptr)); \ + efree(var_hash_ptr); \ + } else { \ 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) Modified: php/php-src/branches/PHP_5_4/ext/standard/var.c =================================================================== --- php/php-src/branches/PHP_5_4/ext/standard/var.c 2011-10-19 07:04:34 UTC (rev 318209) +++ php/php-src/branches/PHP_5_4/ext/standard/var.c 2011-10-19 10:09:24 UTC (rev 318210) @@ -12,7 +12,7 @@ | obtain it through the world-wide-web, please send a note to | | lice...@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Jani Lehtimäki <j...@njet.net> | + | Authors: Jani Lehtimäki <j...@njet.net> | | Thies C. Arntzen <th...@thieso.net> | | Sascha Schumann <sas...@schumann.cx> | +----------------------------------------------------------------------+ @@ -788,7 +788,9 @@ if (ce && ce != PHP_IC_ENTRY && zend_hash_exists(&ce->function_table, "__sleep", sizeof("__sleep"))) { INIT_PZVAL(&fname); ZVAL_STRINGL(&fname, "__sleep", sizeof("__sleep") - 1, 0); + BG(serialize_lock)++; res = call_user_function_ex(CG(function_table), &struc, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC); + BG(serialize_lock)--; if (res == SUCCESS && !EG(exception)) { if (retval_ptr) { Modified: php/php-src/branches/PHP_5_4/ext/standard/var_unserializer.re =================================================================== --- php/php-src/branches/PHP_5_4/ext/standard/var_unserializer.re 2011-10-19 07:04:34 UTC (rev 318209) +++ php/php-src/branches/PHP_5_4/ext/standard/var_unserializer.re 2011-10-19 10:09:24 UTC (rev 318210) @@ -392,7 +392,9 @@ zend_hash_exists(&Z_OBJCE_PP(rval)->function_table, "__wakeup", sizeof("__wakeup"))) { INIT_PZVAL(&fname); ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1, 0); + BG(serialize_lock)++; call_user_function_ex(CG(function_table), rval, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC); + BG(serialize_lock)--; } if (retval_ptr) Modified: php/php-src/trunk/ext/standard/basic_functions.h =================================================================== --- php/php-src/trunk/ext/standard/basic_functions.h 2011-10-19 07:04:34 UTC (rev 318209) +++ php/php-src/trunk/ext/standard/basic_functions.h 2011-10-19 10:09:24 UTC (rev 318210) @@ -204,6 +204,7 @@ /* var.c */ zend_class_entry *incomplete_class; + unsigned serialize_lock; /* whether to use the locally supplied var_hash instead (__sleep/__wakeup) */ struct { void *var_hash; unsigned level; Modified: php/php-src/trunk/ext/standard/php_var.h =================================================================== --- php/php-src/trunk/ext/standard/php_var.h 2011-10-19 07:04:34 UTC (rev 318209) +++ php/php-src/trunk/ext/standard/php_var.h 2011-10-19 10:09:24 UTC (rev 318210) @@ -12,7 +12,7 @@ | obtain it through the world-wide-web, please send a note to | | lice...@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Author: Jani Lehtimäki <j...@njet.net> | + | Author: Jani Lehtimäki <j...@njet.net> | +----------------------------------------------------------------------+ */ @@ -54,52 +54,62 @@ #define PHP_VAR_SERIALIZE_INIT(var_hash_ptr) \ do { \ - if (BG(serialize).level) { \ + /* fprintf(stderr, "SERIALIZE_INIT == lock: %u, level: %u\n", BG(serialize_lock), BG(serialize).level); */ \ + if (BG(serialize_lock) || !BG(serialize).level) { \ + ALLOC_HASHTABLE(var_hash_ptr); \ + zend_hash_init((var_hash_ptr), 10, NULL, NULL, 0); \ + if (!BG(serialize_lock)) { \ + BG(serialize).var_hash = (var_hash_ptr); \ + BG(serialize).level = 1; \ + } \ + } else { \ (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_SERIALIZE_DESTROY(var_hash_ptr) \ do { \ - if (BG(serialize).level) { \ + /* fprintf(stderr, "SERIALIZE_DESTROY == lock: %u, level: %u\n", BG(serialize_lock), BG(serialize).level); */ \ + if (BG(serialize_lock) || !BG(serialize).level) { \ + zend_hash_destroy((var_hash_ptr)); \ + FREE_HASHTABLE(var_hash_ptr); \ + } else { \ 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) { \ + /* fprintf(stderr, "UNSERIALIZE_INIT == lock: %u, level: %u\n", BG(serialize_lock), BG(unserialize).level); */ \ + if (BG(serialize_lock) || !BG(unserialize).level) { \ + (var_hash_ptr) = ecalloc(1, sizeof(struct php_unserialize_data)); \ + if (!BG(serialize_lock)) { \ + BG(unserialize).var_hash = (var_hash_ptr); \ + BG(unserialize).level = 1; \ + } \ + } else { \ (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) { \ + /* fprintf(stderr, "UNSERIALIZE_DESTROY == lock: %u, level: %u\n", BG(serialize_lock), BG(unserialize).level); */ \ + if (BG(serialize_lock) || !BG(unserialize).level) { \ + var_destroy(&(var_hash_ptr)); \ + efree(var_hash_ptr); \ + } else { \ 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) Modified: php/php-src/trunk/ext/standard/var.c =================================================================== --- php/php-src/trunk/ext/standard/var.c 2011-10-19 07:04:34 UTC (rev 318209) +++ php/php-src/trunk/ext/standard/var.c 2011-10-19 10:09:24 UTC (rev 318210) @@ -12,7 +12,7 @@ | obtain it through the world-wide-web, please send a note to | | lice...@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Jani Lehtimäki <j...@njet.net> | + | Authors: Jani Lehtimäki <j...@njet.net> | | Thies C. Arntzen <th...@thieso.net> | | Sascha Schumann <sas...@schumann.cx> | +----------------------------------------------------------------------+ @@ -788,7 +788,9 @@ if (ce && ce != PHP_IC_ENTRY && zend_hash_exists(&ce->function_table, "__sleep", sizeof("__sleep"))) { INIT_PZVAL(&fname); ZVAL_STRINGL(&fname, "__sleep", sizeof("__sleep") - 1, 0); + BG(serialize_lock)++; res = call_user_function_ex(CG(function_table), &struc, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC); + BG(serialize_lock)--; if (res == SUCCESS && !EG(exception)) { if (retval_ptr) { Modified: php/php-src/trunk/ext/standard/var_unserializer.re =================================================================== --- php/php-src/trunk/ext/standard/var_unserializer.re 2011-10-19 07:04:34 UTC (rev 318209) +++ php/php-src/trunk/ext/standard/var_unserializer.re 2011-10-19 10:09:24 UTC (rev 318210) @@ -392,7 +392,9 @@ zend_hash_exists(&Z_OBJCE_PP(rval)->function_table, "__wakeup", sizeof("__wakeup"))) { INIT_PZVAL(&fname); ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1, 0); + BG(serialize_lock)++; call_user_function_ex(CG(function_table), rval, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC); + BG(serialize_lock)--; } if (retval_ptr)
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php