mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Fix Bug #55801 Behavior of unserialize has changed:
(un)serialize in __wakeup/__sleep now use clean var_hashes
This commit is contained in:
parent
f2ce9b406b
commit
b6921369b5
4 changed files with 34 additions and 19 deletions
|
@ -204,6 +204,7 @@ typedef struct _php_basic_globals {
|
|||
|
||||
/* 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;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Jani Lehtimäki <jkl@njet.net> |
|
||||
| Author: Jani Lehtimäki <jkl@njet.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
@ -54,52 +54,62 @@ PHPAPI int php_var_unserialize(zval **rval, const unsigned char **p, const unsig
|
|||
|
||||
#define PHP_VAR_SERIALIZE_INIT(var_hash_ptr) \
|
||||
do { \
|
||||
if (BG(serialize).level) { \
|
||||
(var_hash_ptr) = BG(serialize).var_hash; \
|
||||
++BG(serialize).level; \
|
||||
} else { \
|
||||
/* 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); \
|
||||
BG(serialize).var_hash = (var_hash_ptr); \
|
||||
BG(serialize).level = 1; \
|
||||
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; \
|
||||
} \
|
||||
} 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)
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Jani Lehtimäki <jkl@njet.net> |
|
||||
| Authors: Jani Lehtimäki <jkl@njet.net> |
|
||||
| Thies C. Arntzen <thies@thieso.net> |
|
||||
| Sascha Schumann <sascha@schumann.cx> |
|
||||
+----------------------------------------------------------------------+
|
||||
|
@ -788,7 +788,9 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var
|
|||
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) {
|
||||
|
|
|
@ -392,7 +392,9 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
|
|||
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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue