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

Reply via email to