diff --git a/Zend/Optimizer/zend_optimizer.c b/Zend/Optimizer/zend_optimizer.c index b57ad3ad4268..f8cbefdaaf2b 100644 --- a/Zend/Optimizer/zend_optimizer.c +++ b/Zend/Optimizer/zend_optimizer.c @@ -779,6 +779,9 @@ static bool zend_optimizer_ignore_class(zval *ce_zv, const zend_string *filename const zend_class_entry *ce = Z_PTR_P(ce_zv); if (ce->ce_flags & ZEND_ACC_PRELOADED) { + if (CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE) { + return true; + } const Bucket *ce_bucket = (const Bucket*)((uintptr_t)ce_zv - XtOffsetOf(Bucket, val)); size_t offset = ce_bucket - EG(class_table)->arData; if (offset < EG(persistent_classes_count)) { @@ -797,6 +800,9 @@ static bool zend_optimizer_ignore_function(zval *fbc_zv, const zend_string *file return false; } else if (fbc->type == ZEND_USER_FUNCTION) { if (fbc->op_array.fn_flags & ZEND_ACC_PRELOADED) { + if (CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE) { + return true; + } const Bucket *fbc_bucket = (const Bucket*)((uintptr_t)fbc_zv - XtOffsetOf(Bucket, val)); size_t offset = fbc_bucket - EG(function_table)->arData; if (offset < EG(persistent_functions_count)) { diff --git a/ext/opcache/tests/gh21052.phpt b/ext/opcache/tests/gh21052.phpt new file mode 100644 index 000000000000..d9d0430b9eef --- /dev/null +++ b/ext/opcache/tests/gh21052.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-21052: Preloaded constant erroneously propagated to file-cached script +--CREDITS-- +Grummfy +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache="{TMP}" +opcache.preload={PWD}/gh21052_a.inc +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + string(3) "foo" +} +array(1) { + [0]=> + string(3) "foo" +} +array(1) { + [0]=> + string(3) "foo" +} diff --git a/ext/opcache/tests/gh21052_a.inc b/ext/opcache/tests/gh21052_a.inc new file mode 100644 index 000000000000..f9614369798b --- /dev/null +++ b/ext/opcache/tests/gh21052_a.inc @@ -0,0 +1,13 @@ +refcount++; diff --git a/ext/pcre/tests/preg_match_frameless_leak.phpt b/ext/pcre/tests/preg_match_frameless_leak.phpt new file mode 100644 index 000000000000..52bbfeceee0d --- /dev/null +++ b/ext/pcre/tests/preg_match_frameless_leak.phpt @@ -0,0 +1,26 @@ +--TEST-- +Memory leak in preg_match() frameless function with invalid regex and object arguments +--FILE-- +val = $val; + } + public function __toString() { + return $this->val; + } +} + +$regex = new Str("invalid regex"); +$subject = new Str("some subject"); + +// Running in a loop to ensure leak detection if run with memory tools +for ($i = 0; $i < 100; $i++) { + @preg_match($regex, $subject); +} + +echo "Done"; +?> +--EXPECT-- +Done