Skip to content

Commit

Permalink
Properly release zend_ast_op_array in OPcache
Browse files Browse the repository at this point in the history
[Diff by Ilija, commit message by Tim]
  • Loading branch information
iluuu1994 authored and TimWolla committed Feb 20, 2025
1 parent 6e076a4 commit 9a7cd28
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 0 deletions.
3 changes: 3 additions & 0 deletions ext/opcache/zend_persist.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ static zend_ast *zend_persist_ast(zend_ast *ast)
node = (zend_ast *) copy;
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
zend_ast_op_array *copy = zend_shared_memdup(ast, sizeof(zend_ast_op_array));
/* We're holding a separate reference to the op_array in the AST. Release it
* early because zend_persist_op_array() is destructive. */
destroy_op_array(copy->op_array);
zval z;
ZVAL_PTR(&z, copy->op_array);
zend_persist_op_array(&z);
Expand Down
8 changes: 8 additions & 0 deletions ext/opcache/zend_persist_calc.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ static void zend_persist_ast_calc(zend_ast *ast)
zval z;
ZVAL_PTR(&z, zend_ast_get_op_array(ast)->op_array);
zend_persist_op_array_calc(&z);

/* If op_array is shared, the function name refcount is still incremented for each use,
* so we need to release it here. We remembered the original function name in xlat. */
zend_string *old_function_name =
zend_shared_alloc_get_xlat_entry(&zend_ast_get_op_array(ast)->op_array->function_name);
if (old_function_name) {
zend_string_release_ex(old_function_name, 0);
}
} else if (zend_ast_is_decl(ast)) {
/* Not implemented. */
ZEND_UNREACHABLE();
Expand Down

0 comments on commit 9a7cd28

Please sign in to comment.