Skip to content

Commit

Permalink
Avoid registering top functions with opcache_compile_file()
Browse files Browse the repository at this point in the history
Previously, this only worked for classes. It worked by preventing early binding,
and then declaring the class at runtime. Instead of doing that, we now avoid
calling zend_accel_load_script() completely, which prevents the functions from
being added to the function table.

Fixes GH-16668
  • Loading branch information
iluuu1994 committed Nov 19, 2024
1 parent 9b3af02 commit 43026a5
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 5 deletions.
3 changes: 1 addition & 2 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -9120,8 +9120,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel)
}

/* We currently don't early-bind classes that implement interfaces or use traits */
if (!ce->num_interfaces && !ce->num_traits && !ce->num_hooked_prop_variance_checks
&& !(CG(compiler_options) & ZEND_COMPILE_WITHOUT_EXECUTION)) {
if (!ce->num_interfaces && !ce->num_traits && !ce->num_hooked_prop_variance_checks) {
if (toplevel) {
if (extends_ast) {
zend_class_entry *parent_ce = zend_lookup_class_ex(
Expand Down
9 changes: 9 additions & 0 deletions ext/opcache/tests/gh16668/gh16668.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

function test() {
echo __FUNCTION__, "()\n";
}

function a() {}
function b() {}
function c() {}
20 changes: 20 additions & 0 deletions ext/opcache/tests/gh16668/gh16668.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--TEST--
GH-16668: opcache_compile_file() mistakenly declares top functions
--INI--
opcache.enable=1
opcache.enable_cli=1
--EXTENSIONS--
opcache
--FILE--
<?php
opcache_compile_file(__DIR__ . '/gh16668.inc');
opcache_compile_file(__DIR__ . '/gh16668.inc');
var_dump(function_exists('test'));
require __DIR__ . '/gh16668.inc';
var_dump(function_exists('test'));
test();
?>
--EXPECT--
bool(false)
bool(true)
test()
4 changes: 1 addition & 3 deletions ext/opcache/zend_accelerator_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -981,9 +981,7 @@ ZEND_FUNCTION(opcache_compile_file)

CG(compiler_options) = orig_compiler_options;

if(op_array != NULL) {
destroy_op_array(op_array);
efree(op_array);
if (op_array == (void *) -1) {
RETVAL_TRUE;
} else {
RETVAL_FALSE;
Expand Down
6 changes: 6 additions & 0 deletions ext/opcache/zend_accelerator_util_funcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,12 @@ static void zend_accel_do_delayed_early_binding(

zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, int from_shared_memory)
{
if (CG(compiler_options) & ZEND_COMPILE_WITHOUT_EXECUTION) {
/* Not a pretty API, but we need to distinguish between successful and
* unsuccessful compilations. */
return (void *) -1;
}

zend_op_array *op_array;

op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
Expand Down

0 comments on commit 43026a5

Please sign in to comment.