summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2018-12-12 20:04:36 +0300
committerDmitry Stogov <dmitry@zend.com>2018-12-12 20:04:36 +0300
commit71f430cf067aa7c7ecc4a813df7d6cad19bf8148 (patch)
tree6991b2a18260e62f9132864340eba5bd169fc333
parent8c781c1c203f1e4b30aef2446a0ece7ebba6c76b (diff)
downloadphp-git-71f430cf067aa7c7ecc4a813df7d6cad19bf8148.tar.gz
Improve unserialize()
-rw-r--r--ext/standard/var.c14
-rw-r--r--ext/standard/var_unserializer.re16
2 files changed, 22 insertions, 8 deletions
diff --git a/ext/standard/var.c b/ext/standard/var.c
index f6b6bcf47f..108bafca8b 100644
--- a/ext/standard/var.c
+++ b/ext/standard/var.c
@@ -1102,15 +1102,25 @@ PHP_FUNCTION(unserialize)
php_var_unserialize_set_allowed_classes(var_hash, class_hash);
}
- retval = var_tmp_var(&var_hash);
+ if (BG(unserialize).level > 1) {
+ retval = var_tmp_var(&var_hash);
+ } else {
+ retval = return_value;
+ }
if (!php_var_unserialize(retval, &p, p + buf_len, &var_hash)) {
if (!EG(exception)) {
php_error_docref(NULL, E_NOTICE, "Error at offset " ZEND_LONG_FMT " of %zd bytes",
(zend_long)((char*)p - buf), buf_len);
}
+ if (BG(unserialize).level <= 1) {
+ zval_ptr_dtor(return_value);
+ }
RETVAL_FALSE;
- } else {
+ } else if (BG(unserialize).level > 1) {
ZVAL_COPY(return_value, retval);
+ } else if (Z_REFCOUNTED_P(return_value)) {
+ zend_refcounted *ref = Z_COUNTED_P(return_value);
+ gc_check_possible_root(ref);
}
if (class_hash) {
diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re
index 1b39856091..17f330815c 100644
--- a/ext/standard/var_unserializer.re
+++ b/ext/standard/var_unserializer.re
@@ -109,11 +109,13 @@ static inline void var_push(php_unserialize_data_t *var_hashx, zval *rval)
PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval *rval)
{
- zval *tmp_var = var_tmp_var(var_hashx);
- if (!tmp_var) {
- return;
- }
- ZVAL_COPY(tmp_var, rval);
+ if (Z_REFCOUNTED_P(rval)) {
+ zval *tmp_var = var_tmp_var(var_hashx);
+ if (!tmp_var) {
+ return;
+ }
+ ZVAL_COPY(tmp_var, rval);
+ }
}
PHPAPI zval *var_tmp_var(php_unserialize_data_t *var_hashx)
@@ -510,7 +512,9 @@ string_key:
return 0;
}
- var_push_dtor(var_hash, data);
+ if (BG(unserialize).level > 1) {
+ var_push_dtor(var_hash, data);
+ }
zval_ptr_dtor_str(&key);
if (elements && *(*p-1) != ';' && *(*p-1) != '}') {