From 6085c82122f7883b0c76b2bff187722f1863ace8 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sat, 11 Jul 2020 18:46:51 +0200 Subject: [PATCH] Fix free of uninitialized memory in MATCH_ERROR As suggested by Tyson Andre: https://github.com/php/php-src/pull/5371#issuecomment-657081464 Also fix line number of unhandled match error --- Zend/tests/match/037.phpt | 6 +++--- Zend/zend_compile.c | 32 ++++++++++++++++---------------- ext/opcache/tests/match/001.phpt | 16 ++++++++-------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Zend/tests/match/037.phpt b/Zend/tests/match/037.phpt index abd5dcfdc1855..d3591fbfcba26 100644 --- a/Zend/tests/match/037.phpt +++ b/Zend/tests/match/037.phpt @@ -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" diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index cfe058b72be30..2f278fdfffab0 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -5297,6 +5297,22 @@ 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); + 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_ast *arm_ast = arms->child[i]; zend_ast *body_ast = arm_ast->child[1]; @@ -5358,22 +5374,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]); } diff --git a/ext/opcache/tests/match/001.phpt b/ext/opcache/tests/match/001.phpt index 0f6c4f07075c8..7963733594fa8 100644 --- a/ext/opcache/tests/match/001.phpt +++ b/ext/opcache/tests/match/001.phpt @@ -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"