diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2021-02-15 14:58:59 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2021-02-15 14:58:59 +0100 |
commit | 882862563a8281457afb9c5ad93763605e295270 (patch) | |
tree | bf7ecee1ad2a4de1db5c858c404ce05e73e95f40 | |
parent | c70220205e20005ad916289ea6958d156fac54da (diff) | |
parent | 7b7d99839c2e2886ecf159952552c9964bd80481 (diff) | |
download | php-git-882862563a8281457afb9c5ad93763605e295270.tar.gz |
Merge branch 'PHP-7.4' into PHP-8.0
* PHP-7.4:
Fix symtable cache being used while cleaning symtable
-rw-r--r-- | Zend/tests/symtable_cache_recursive_dtor.phpt | 19 | ||||
-rw-r--r-- | Zend/zend_execute.c | 7 |
2 files changed, 23 insertions, 3 deletions
diff --git a/Zend/tests/symtable_cache_recursive_dtor.phpt b/Zend/tests/symtable_cache_recursive_dtor.phpt new file mode 100644 index 0000000000..def0816a66 --- /dev/null +++ b/Zend/tests/symtable_cache_recursive_dtor.phpt @@ -0,0 +1,19 @@ +--TEST-- +Symtable cache slots may be acquired while cleaning symtable +--FILE-- +<?php +class A { + // Must be larger than the symtable cache. + static $max = 40; + function __destruct() { + if (self::$max-- < 0) return; + $x = 'y'; + $$x = new a; + } +} +new A; + +?> +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index bc964c1ad1..edf6c61794 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -3396,12 +3396,13 @@ ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_val ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table) /* {{{ */ { + /* Clean before putting into the cache, since clean could call dtors, + * which could use the cached hash. Also do this before the check for + * available cache slots, as those may be used by a dtor as well. */ + zend_symtable_clean(symbol_table); if (EG(symtable_cache_ptr) >= EG(symtable_cache_limit)) { zend_array_destroy(symbol_table); } else { - /* clean before putting into the cache, since clean - could call dtors, which could use cached hash */ - zend_symtable_clean(symbol_table); *(EG(symtable_cache_ptr)++) = symbol_table; } } |