diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | ext/standard/tests/serialize/bug73154.phpt | 16 | ||||
-rw-r--r-- | ext/standard/var.c | 16 |
3 files changed, 27 insertions, 7 deletions
@@ -47,7 +47,7 @@ PHP NEWS parameter). (Bruce Weirdan) . Fixed bug #70213 (Unserialize context shared on double class lookup). (Taoguang Chen) - + . Fixed bug #73154 (serialize object with __sleep function crash). (Nikita) - Zlib: . Fixed bug #73373 (deflate_add does not verify that output was not truncated). diff --git a/ext/standard/tests/serialize/bug73154.phpt b/ext/standard/tests/serialize/bug73154.phpt new file mode 100644 index 0000000000..8d0f188bf7 --- /dev/null +++ b/ext/standard/tests/serialize/bug73154.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #73154: serialize object with __sleep function crash +--FILE-- +<?php +class a { + public $a; + public function __sleep() { + $this->a=null; + return array(); + } +} +$s = 'a:1:{i:0;O:1:"a":1:{s:1:"a";R:2;}}'; +var_dump(serialize(unserialize($s))); +?> +--EXPECT-- +string(22) "a:1:{i:0;O:1:"a":0:{}}" diff --git a/ext/standard/var.c b/ext/standard/var.c index 88719ccb64..c04afae4dc 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -860,9 +860,6 @@ again: return; case IS_OBJECT: { - zval retval; - zval fname; - int res; zend_class_entry *ce = Z_OBJCE_P(struc); if (ce->serialize != NULL) { @@ -891,32 +888,39 @@ again: } if (ce != PHP_IC_ENTRY && zend_hash_str_exists(&ce->function_table, "__sleep", sizeof("__sleep")-1)) { + zval fname, tmp, retval; + int res; + + ZVAL_COPY(&tmp, struc); ZVAL_STRINGL(&fname, "__sleep", sizeof("__sleep") - 1); BG(serialize_lock)++; - res = call_user_function_ex(CG(function_table), struc, &fname, &retval, 0, 0, 1, NULL); + res = call_user_function_ex(CG(function_table), &tmp, &fname, &retval, 0, 0, 1, NULL); BG(serialize_lock)--; zval_dtor(&fname); if (EG(exception)) { zval_ptr_dtor(&retval); + zval_ptr_dtor(&tmp); return; } if (res == SUCCESS) { if (Z_TYPE(retval) != IS_UNDEF) { if (HASH_OF(&retval)) { - php_var_serialize_class(buf, struc, &retval, var_hash); + php_var_serialize_class(buf, &tmp, &retval, var_hash); } else { php_error_docref(NULL, E_NOTICE, "__sleep should return an array only containing the names of instance-variables to serialize"); /* we should still add element even if it's not OK, * since we already wrote the length of the array before */ smart_str_appendl(buf,"N;", 2); } - zval_ptr_dtor(&retval); } + zval_ptr_dtor(&retval); + zval_ptr_dtor(&tmp); return; } zval_ptr_dtor(&retval); + zval_ptr_dtor(&tmp); } /* fall-through */ |