Don't free FETCH_W operand if GLOBAL_LOCK

The error path performed the free unconditionally, while we should
not do it for GLOBAL_LOCK.

Fixes oss-fuzz #39868.
This commit is contained in:
Nikita Popov 2021-10-12 12:44:35 +02:00
parent 2127b49c65
commit a2e3ca1f5b
3 changed files with 24 additions and 2 deletions

View File

@ -0,0 +1,14 @@
--TEST--
To string conversion failure in global
--FILE--
<?php
try {
global ${new stdClass};
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECT--
Object of class stdClass could not be converted to string

View File

@ -1708,7 +1708,9 @@ ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type)
}
name = zval_try_get_tmp_string(varname, &tmp_name);
if (UNEXPECTED(!name)) {
FREE_OP1();
if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
FREE_OP1();
}
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}

View File

@ -9465,7 +9465,9 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_ad
}
name = zval_try_get_tmp_string(varname, &tmp_name);
if (UNEXPECTED(!name)) {
if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
}
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
@ -17315,7 +17317,9 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_ad
}
name = zval_try_get_tmp_string(varname, &tmp_name);
if (UNEXPECTED(!name)) {
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
}
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
@ -45659,7 +45663,9 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_ad
}
name = zval_try_get_tmp_string(varname, &tmp_name);
if (UNEXPECTED(!name)) {
if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
}
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}