mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
Create reference wrappers in SEND_UNPACK if necessary
Even if we can't actually pass by reference, we still need to create the REFERENCE wrapper to satisfy the calling convention. The particular test case would crash with JIT, because the existence of the reference was assumed. Fixes oss-fuzz #39440.
This commit is contained in:
parent
d0860f67ca
commit
e11faad233
18
Zend/tests/unpack_iterator_by_ref_type_check.phpt
Normal file
18
Zend/tests/unpack_iterator_by_ref_type_check.phpt
Normal file
@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Unpack iterator by reference with type check
|
||||
--FILE--
|
||||
<?php
|
||||
function test(T &$a) {
|
||||
}
|
||||
function gen() {
|
||||
yield null;
|
||||
}
|
||||
try {
|
||||
test(...gen());
|
||||
} catch (TypeError $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Cannot pass by-reference argument 1 of test() by unpacking a Traversable, passing by-value instead in %s on line %d
|
||||
test(): Argument #1 ($a) must be of type T, null given, called in %s on line %d
|
@ -5126,6 +5126,9 @@ ZEND_VM_C_LABEL(send_again):
|
||||
break;
|
||||
}
|
||||
|
||||
ZVAL_DEREF(arg);
|
||||
Z_TRY_ADDREF_P(arg);
|
||||
|
||||
if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
|
||||
zend_error(
|
||||
E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()"
|
||||
@ -5134,9 +5137,11 @@ ZEND_VM_C_LABEL(send_again):
|
||||
EX(call)->func->common.scope ? "::" : "",
|
||||
ZSTR_VAL(EX(call)->func->common.function_name)
|
||||
);
|
||||
ZVAL_NEW_REF(top, arg);
|
||||
} else {
|
||||
ZVAL_COPY_VALUE(top, arg);
|
||||
}
|
||||
|
||||
ZVAL_COPY_DEREF(top, arg);
|
||||
zend_string_release(name);
|
||||
} else {
|
||||
if (have_named_params) {
|
||||
@ -5145,6 +5150,11 @@ ZEND_VM_C_LABEL(send_again):
|
||||
break;
|
||||
}
|
||||
|
||||
zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1);
|
||||
top = ZEND_CALL_ARG(EX(call), arg_num);
|
||||
ZVAL_DEREF(arg);
|
||||
Z_TRY_ADDREF_P(arg);
|
||||
|
||||
if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
|
||||
zend_error(
|
||||
E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()"
|
||||
@ -5153,12 +5163,11 @@ ZEND_VM_C_LABEL(send_again):
|
||||
EX(call)->func->common.scope ? "::" : "",
|
||||
ZSTR_VAL(EX(call)->func->common.function_name)
|
||||
);
|
||||
ZVAL_NEW_REF(top, arg);
|
||||
} else {
|
||||
ZVAL_COPY_VALUE(top, arg);
|
||||
}
|
||||
|
||||
|
||||
zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1);
|
||||
top = ZEND_CALL_ARG(EX(call), arg_num);
|
||||
ZVAL_COPY_DEREF(top, arg);
|
||||
ZEND_CALL_NUM_ARGS(EX(call))++;
|
||||
}
|
||||
|
||||
|
@ -2248,6 +2248,9 @@ send_again:
|
||||
break;
|
||||
}
|
||||
|
||||
ZVAL_DEREF(arg);
|
||||
Z_TRY_ADDREF_P(arg);
|
||||
|
||||
if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
|
||||
zend_error(
|
||||
E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()"
|
||||
@ -2256,9 +2259,11 @@ send_again:
|
||||
EX(call)->func->common.scope ? "::" : "",
|
||||
ZSTR_VAL(EX(call)->func->common.function_name)
|
||||
);
|
||||
ZVAL_NEW_REF(top, arg);
|
||||
} else {
|
||||
ZVAL_COPY_VALUE(top, arg);
|
||||
}
|
||||
|
||||
ZVAL_COPY_DEREF(top, arg);
|
||||
zend_string_release(name);
|
||||
} else {
|
||||
if (have_named_params) {
|
||||
@ -2267,6 +2272,11 @@ send_again:
|
||||
break;
|
||||
}
|
||||
|
||||
zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1);
|
||||
top = ZEND_CALL_ARG(EX(call), arg_num);
|
||||
ZVAL_DEREF(arg);
|
||||
Z_TRY_ADDREF_P(arg);
|
||||
|
||||
if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
|
||||
zend_error(
|
||||
E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()"
|
||||
@ -2275,12 +2285,11 @@ send_again:
|
||||
EX(call)->func->common.scope ? "::" : "",
|
||||
ZSTR_VAL(EX(call)->func->common.function_name)
|
||||
);
|
||||
ZVAL_NEW_REF(top, arg);
|
||||
} else {
|
||||
ZVAL_COPY_VALUE(top, arg);
|
||||
}
|
||||
|
||||
|
||||
zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1);
|
||||
top = ZEND_CALL_ARG(EX(call), arg_num);
|
||||
ZVAL_COPY_DEREF(top, arg);
|
||||
ZEND_CALL_NUM_ARGS(EX(call))++;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user