From a5e89c5686ef5def07a65bfcd9ae2eb8673413e5 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Wed, 5 Jul 2023 13:16:32 +0200 Subject: [PATCH] Fix trailing if element JMP lineno Having this lineno on the same last compiled element can lead to an incorrectly covered line number. if (true) { if (false) { echo 'Never executed'; } } else { } The echo will be reported as covered because the JMP from the if (true) branch to the end of the else branch has the same lineno as the echo. This is lacking a test because zend_dump.c does not have access to ctx->debug_level and I don't think it's worth adjusting all the cases. Closes GH-11598 --- NEWS | 1 + Zend/zend_compile.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/NEWS b/NEWS index cab2abd6d01..92cb48f0dec 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ PHP NEWS - Core: . Fixed oss-fuzz #60011 (Mis-compilation of by-reference nullsafe operator). (ilutov) + . Fixed line number of JMP instruction over else block. (ilutov) - Date: . Fixed bug GH-11368 (Date modify returns invalid datetime). (Derick) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index ba203cbe2e2..3aee5af1081 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -5420,6 +5420,9 @@ static void zend_compile_if(zend_ast *ast) /* {{{ */ zend_compile_stmt(stmt_ast); if (i != list->children - 1) { + /* Set the lineno of JMP to the position of the if keyword, as we don't want to + * report the last line in the if branch as covered if it hasn't actually executed. */ + CG(zend_lineno) = elem_ast->lineno; jmp_opnums[i] = zend_emit_jump(0); } zend_update_jump_target_to_next(opnum_jmpz);