diff options
author | Nikita Popov <nikic@php.net> | 2017-01-01 19:24:41 +0100 |
---|---|---|
committer | Nikita Popov <nikic@php.net> | 2017-01-01 19:24:41 +0100 |
commit | 4877641962a7ad77fd3d1dac0b59de37a52659a1 (patch) | |
tree | d36ee59ac42a686a8e031d386eb635e1781f1afc /ext/standard/var.c | |
parent | 9f560baef5eacbe3fdb6a23a2d4e1996a30a2d2c (diff) | |
download | php-git-4877641962a7ad77fd3d1dac0b59de37a52659a1.tar.gz |
Fixed bug #73154
The object that is being serialized may be destroyed during the
execution of __sleep(), so operate on a copy instead.
Diffstat (limited to 'ext/standard/var.c')
-rw-r--r-- | ext/standard/var.c | 16 |
1 files changed, 10 insertions, 6 deletions
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 */ |