Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix free of uninitialized memory in MATCH_ERROR #5841

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Zend/tests/match/037.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ var_dump(match(3) {

?>
--EXPECTF--
string(%d) "UnhandledMatchError: Unhandled match value of type bool in %s037.php:5
string(%d) "UnhandledMatchError: Unhandled match value of type bool in %s037.php:4
Stack trace:
#0 {main}"
string(%d) "UnhandledMatchError: Unhandled match value of type int in %s037.php:13
string(%d) "UnhandledMatchError: Unhandled match value of type int in %s037.php:12
Stack trace:
#0 {main}"
string(%d) "UnhandledMatchError: Unhandled match value of type string in %s037.php:21
string(%d) "UnhandledMatchError: Unhandled match value of type string in %s037.php:20
Stack trace:
#0 {main}"
string(3) "foo"
Expand Down
34 changes: 18 additions & 16 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -5297,6 +5297,24 @@ void zend_compile_match(znode *result, zend_ast *ast)
uint32_t cond_count = 0;
uint32_t *jmp_end_opnums = safe_emalloc(sizeof(uint32_t), arms->children, 0);

// The generated default arm is emitted first to avoid live range issues where the tmpvar
// for the arm result is freed even though it has not been initialized yet.
if (!has_default_arm) {
if (!uses_jumptable) {
zend_update_jump_target_to_next(opnum_default_jmp);
iluuu1994 marked this conversation as resolved.
Show resolved Hide resolved
}

if (jumptable) {
zend_op *opline = &CG(active_op_array)->opcodes[opnum_match];
opline->extended_value = get_next_op_number();
}

zend_op *opline = zend_emit_op(NULL, ZEND_MATCH_ERROR, &expr_node, NULL);
if (opline->op1_type == IS_CONST) {
Z_TRY_ADDREF_P(CT_CONSTANT(opline->op1));
}
}
iluuu1994 marked this conversation as resolved.
Show resolved Hide resolved

for (uint32_t i = 0; i < arms->children; ++i) {
zend_ast *arm_ast = arms->child[i];
zend_ast *body_ast = arm_ast->child[1];
Expand Down Expand Up @@ -5358,22 +5376,6 @@ void zend_compile_match(znode *result, zend_ast *ast)
ZVAL_NULL(&result->u.constant);
}

if (!has_default_arm) {
if (!uses_jumptable) {
zend_update_jump_target_to_next(opnum_default_jmp);
}

if (jumptable) {
zend_op *opline = &CG(active_op_array)->opcodes[opnum_match];
opline->extended_value = get_next_op_number();
}

zend_op *opline = zend_emit_op(NULL, ZEND_MATCH_ERROR, &expr_node, NULL);
if (opline->op1_type == IS_CONST) {
Z_TRY_ADDREF_P(CT_CONSTANT(opline->op1));
}
}

for (uint32_t i = 0; i < arms->children; ++i) {
zend_update_jump_target_to_next(jmp_end_opnums[i]);
}
Expand Down
16 changes: 8 additions & 8 deletions ext/opcache/tests/match/001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ test:
; (after optimizer)
; %s
0000 CV0($char) = RECV 1
0001 MATCH CV0($char) "a": 0002, "b": 0003, "c": 0003, "d": 0004, "e": 0005, "f": 0005, "g": 0006, "h": 0007, "i": 0007, default: 0008
0002 RETURN string("a")
0003 RETURN string("b, c")
0004 RETURN string("d")
0005 RETURN string("e, f")
0006 RETURN string("g")
0007 RETURN string("h, i")
0008 MATCH_ERROR CV0($char)
0001 MATCH CV0($char) "a": 0003, "b": 0004, "c": 0004, "d": 0005, "e": 0006, "f": 0006, "g": 0007, "h": 0008, "i": 0008, default: 0002
0002 MATCH_ERROR CV0($char)
0003 RETURN string("a")
0004 RETURN string("b, c")
0005 RETURN string("d")
0006 RETURN string("e, f")
0007 RETURN string("g")
0008 RETURN string("h, i")
string(1) "a"
string(4) "b, c"
string(4) "b, c"
Expand Down