diff options
author | Dmitry Stogov <dmitry@zend.com> | 2018-12-12 20:04:36 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2018-12-12 20:04:36 +0300 |
commit | 71f430cf067aa7c7ecc4a813df7d6cad19bf8148 (patch) | |
tree | 6991b2a18260e62f9132864340eba5bd169fc333 /ext/standard | |
parent | 8c781c1c203f1e4b30aef2446a0ece7ebba6c76b (diff) | |
download | php-git-71f430cf067aa7c7ecc4a813df7d6cad19bf8148.tar.gz |
Improve unserialize()
Diffstat (limited to 'ext/standard')
-rw-r--r-- | ext/standard/var.c | 14 | ||||
-rw-r--r-- | ext/standard/var_unserializer.re | 16 |
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) != '}') { |