Skip to content

Commit 4226c82

Browse files
committed
Fix use-after-free in assign-ref compilation
zend_emit_op_data may reallocate the op_array, so the assignment of the RETURNS_FUNCTION flag may happen on an outdated opline. Restructure the code a bit to set the flag before calling zend_emit_op_data().
1 parent c25104b commit 4226c82

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

Zend/zend_compile.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2822,7 +2822,7 @@ void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */
28222822

28232823
znode target_node, source_node;
28242824
zend_op *opline;
2825-
uint32_t offset;
2825+
uint32_t offset, flags;
28262826

28272827
if (is_this_fetch(target_ast)) {
28282828
zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
@@ -2851,27 +2851,27 @@ void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */
28512851
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use result of built-in function in write context");
28522852
}
28532853

2854+
flags = zend_is_call(source_ast) ? ZEND_RETURNS_FUNCTION : 0;
2855+
28542856
if (opline && opline->opcode == ZEND_FETCH_OBJ_W) {
28552857
opline->opcode = ZEND_ASSIGN_OBJ_REF;
28562858
opline->extended_value &= ~ZEND_FETCH_REF;
2859+
opline->extended_value |= flags;
28572860
zend_emit_op_data(&source_node);
28582861
if (result != NULL) {
28592862
*result = target_node;
28602863
}
28612864
} else if (opline && opline->opcode == ZEND_FETCH_STATIC_PROP_W) {
28622865
opline->opcode = ZEND_ASSIGN_STATIC_PROP_REF;
28632866
opline->extended_value &= ~ZEND_FETCH_REF;
2867+
opline->extended_value |= flags;
28642868
zend_emit_op_data(&source_node);
28652869
if (result != NULL) {
28662870
*result = target_node;
28672871
}
28682872
} else {
28692873
opline = zend_emit_op(result, ZEND_ASSIGN_REF, &target_node, &source_node);
2870-
opline->extended_value = 0;
2871-
}
2872-
2873-
if (zend_is_call(source_ast)) {
2874-
opline->extended_value |= ZEND_RETURNS_FUNCTION;
2874+
opline->extended_value = flags;
28752875
}
28762876
}
28772877
/* }}} */

0 commit comments

Comments
 (0)