From 05affa4c864672beed1e3e9f1b1f68b0c0bf372c Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 1 Jun 2005 10:53:57 +0000 Subject: [PATCH] Fixed bug #30791 (magic methods (__sleep/__wakeup/__toString) call __call if object is overloaded) --- NEWS | 2 ++ Zend/tests/bug30791.phpt | 23 +++++++++++++++++++++++ Zend/zend_object_handlers.c | 3 +++ ext/standard/var.c | 3 ++- ext/standard/var_unserializer.c | 3 ++- ext/standard/var_unserializer.re | 3 ++- 6 files changed, 34 insertions(+), 3 deletions(-) create mode 100755 Zend/tests/bug30791.phpt diff --git a/NEWS b/NEWS index 81c234e069..eb3438006c 100644 --- a/NEWS +++ b/NEWS @@ -111,6 +111,8 @@ PHP NEWS - Fixed bug #30889 (Conflict between __get/__set and ++ operator). (Dmitry) - Fixed bug #30833 (array_count_values() modifying input array). (Tony) - Fixed bug #30819 (Better support for LDAP SASL bind). (Jani) +- Fixed bug #30791 (magic methods (__sleep/__wakeup/__toString) call __call if + object is overloaded). (Dmitry) - Fixed bug #30707 (Segmentation fault on exception in method). (Stas, Dmitry) - Fixed bug #30702 (cannot initialize class variable from class constant). (Dmitry) diff --git a/Zend/tests/bug30791.phpt b/Zend/tests/bug30791.phpt new file mode 100755 index 0000000000..f56bcfb6e7 --- /dev/null +++ b/Zend/tests/bug30791.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #30791 magic methods (__sleep/__wakeup/__toString) call __call if object is overloaded +--FILE-- + +--EXPECT-- +Object id #1 +Object id #2 +object(a)#2 (1) { + ["a"]=> + int(4) +} diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index c1b134d15b..2886d1c7f4 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -954,6 +954,9 @@ ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int ty switch (type) { case IS_STRING: + if (!zend_hash_exists(&Z_OBJCE_P(readobj)->function_table, "__tostring", sizeof("__tostring"))) { + return FAILURE; + } ZVAL_STRING(&fname, "__tostring", 0); if (call_user_function_ex(NULL, &readobj, &fname, &retval, 0, NULL, 0, NULL TSRMLS_CC) == SUCCESS) { if (retval) { diff --git a/ext/standard/var.c b/ext/standard/var.c index c07696aabe..286fb1e5a1 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -671,7 +671,8 @@ static void php_var_serialize_intern(smart_str *buf, zval **struc, HashTable *va zval fname; int res; - if(Z_OBJCE_PP(struc) != PHP_IC_ENTRY) { + if (Z_OBJCE_PP(struc) != PHP_IC_ENTRY && + zend_hash_exists(&Z_OBJCE_PP(struc)->function_table, "__sleep", sizeof("__sleep"))) { INIT_PZVAL(&fname); ZVAL_STRINGL(&fname, "__sleep", sizeof("__sleep") - 1, 0); res = call_user_function_ex(CG(function_table), struc, &fname, diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index f01fe2adc8..0db64025a3 100644 --- a/ext/standard/var_unserializer.c +++ b/ext/standard/var_unserializer.c @@ -298,7 +298,8 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, long elements) return 0; } - if(Z_OBJCE_PP(rval) != PHP_IC_ENTRY) { + if (Z_OBJCE_PP(rval) != PHP_IC_ENTRY && + zend_hash_exists(&Z_OBJCE_PP(rval)->function_table, "__wakeup", sizeof("__wakeup"))) { INIT_PZVAL(&fname); ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1, 0); call_user_function_ex(CG(function_table), rval, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC); diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index 821b50b97c..94bbacccc7 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -301,7 +301,8 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, long elements) return 0; } - if(Z_OBJCE_PP(rval) != PHP_IC_ENTRY) { + if (Z_OBJCE_PP(rval) != PHP_IC_ENTRY && + zend_hash_exists(&Z_OBJCE_PP(rval)->function_table, "__wakeup", sizeof("__wakeup"))) { INIT_PZVAL(&fname); ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1, 0); call_user_function_ex(CG(function_table), rval, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC); -- 2.50.1