mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1: Fix memory leak
This commit is contained in:
commit
5ad8b3bcfa
3 changed files with 49 additions and 0 deletions
23
Zend/tests/temporary_cleaning_017.phpt
Normal file
23
Zend/tests/temporary_cleaning_017.phpt
Normal file
|
@ -0,0 +1,23 @@
|
|||
--TEST--
|
||||
Live range & free on return & TMP var of RETURN opcode
|
||||
--FILE--
|
||||
<?php
|
||||
class bar{
|
||||
public $y;
|
||||
function __destruct() {
|
||||
y;
|
||||
}
|
||||
}
|
||||
foreach(new bar as $y) {
|
||||
try {
|
||||
return new Exception;
|
||||
} catch(y) {
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Undefined constant "y" in %stemporary_cleaning_017.php:5
|
||||
Stack trace:
|
||||
#0 %stemporary_cleaning_017.php(10): bar->__destruct()
|
||||
#1 {main}
|
||||
thrown in %stemporary_cleaning_017.php on line 5
|
|
@ -7922,6 +7922,19 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
|
|||
*/
|
||||
const zend_live_range *range = find_live_range(
|
||||
&EX(func)->op_array, throw_op_num, throw_op->op1.var);
|
||||
/* free op1 of the corresponding RETURN */
|
||||
for (i = throw_op_num; i < range->end; i++) {
|
||||
if (EX(func)->op_array.opcodes[i].opcode == ZEND_FREE
|
||||
|| EX(func)->op_array.opcodes[i].opcode == ZEND_FE_FREE) {
|
||||
/* pass */
|
||||
} else {
|
||||
if (EX(func)->op_array.opcodes[i].opcode == ZEND_RETURN
|
||||
&& (EX(func)->op_array.opcodes[i].op1_type & (IS_VAR|IS_TMP_VAR))) {
|
||||
zval_ptr_dtor(EX_VAR(EX(func)->op_array.opcodes[i].op1.var));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
throw_op_num = range->end;
|
||||
}
|
||||
|
||||
|
|
13
Zend/zend_vm_execute.h
generated
13
Zend/zend_vm_execute.h
generated
|
@ -3175,6 +3175,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(
|
|||
*/
|
||||
const zend_live_range *range = find_live_range(
|
||||
&EX(func)->op_array, throw_op_num, throw_op->op1.var);
|
||||
/* free op1 of the corresponding RETURN */
|
||||
for (i = throw_op_num; i < range->end; i++) {
|
||||
if (EX(func)->op_array.opcodes[i].opcode == ZEND_FREE
|
||||
|| EX(func)->op_array.opcodes[i].opcode == ZEND_FE_FREE) {
|
||||
/* pass */
|
||||
} else {
|
||||
if (EX(func)->op_array.opcodes[i].opcode == ZEND_RETURN
|
||||
&& (EX(func)->op_array.opcodes[i].op1_type & (IS_VAR|IS_TMP_VAR))) {
|
||||
zval_ptr_dtor(EX_VAR(EX(func)->op_array.opcodes[i].op1.var));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
throw_op_num = range->end;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue