Revert "Allow internal functions to return values by reference (this was disabled in implementation of DO_ICALL, but enabled in DO_FCALL)."

This reverts commit da781a5ac2.
This commit is contained in:
Dmitry Stogov 2017-10-17 13:25:19 +03:00
parent da781a5ac2
commit 61ef91bf0d
6 changed files with 45 additions and 45 deletions

View File

@ -3480,12 +3480,11 @@ ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
fbc->internal_function.handler(call, ret);
#if ZEND_DEBUG
if (!EG(exception) && call->func) {
ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ||
!Z_ISREF_P(ret));
}
ZEND_ASSERT(
EG(exception) || !call->func ||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
ZEND_ASSERT(!Z_ISREF_P(ret));
#endif
EG(current_execute_data) = execute_data;
@ -3583,8 +3582,8 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
if (!EG(exception) && call->func) {
ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ||
!Z_ISREF_P(ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
}
#endif
@ -3677,8 +3676,8 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
if (!EG(exception) && call->func) {
ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ||
!Z_ISREF_P(ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
}
#endif
@ -7838,12 +7837,10 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY)
}
#if ZEND_DEBUG
if (!EG(exception) && call->func) {
ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ||
!Z_ISREF_P(ret));
}
ZEND_ASSERT(
EG(exception) || !call->func ||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
#endif
EG(current_execute_data) = call->prev_execute_data;

View File

@ -573,12 +573,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV
fbc->internal_function.handler(call, ret);
#if ZEND_DEBUG
if (!EG(exception) && call->func) {
ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ||
!Z_ISREF_P(ret));
}
ZEND_ASSERT(
EG(exception) || !call->func ||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
ZEND_ASSERT(!Z_ISREF_P(ret));
#endif
EG(current_execute_data) = execute_data;
@ -618,12 +617,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV
fbc->internal_function.handler(call, ret);
#if ZEND_DEBUG
if (!EG(exception) && call->func) {
ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ||
!Z_ISREF_P(ret));
}
ZEND_ASSERT(
EG(exception) || !call->func ||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
ZEND_ASSERT(!Z_ISREF_P(ret));
#endif
EG(current_execute_data) = execute_data;
@ -743,8 +741,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
if (!EG(exception) && call->func) {
ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ||
!Z_ISREF_P(ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
}
#endif
@ -821,8 +819,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
if (!EG(exception) && call->func) {
ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ||
!Z_ISREF_P(ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
}
#endif
@ -915,8 +913,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
if (!EG(exception) && call->func) {
ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ||
!Z_ISREF_P(ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
}
#endif
@ -1040,8 +1038,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
if (!EG(exception) && call->func) {
ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ||
!Z_ISREF_P(ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
}
#endif
@ -2034,12 +2032,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
}
#if ZEND_DEBUG
if (!EG(exception) && call->func) {
ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ||
!Z_ISREF_P(ret));
}
ZEND_ASSERT(
EG(exception) || !call->func ||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
#endif
EG(current_execute_data) = call->prev_execute_data;

View File

@ -2,7 +2,7 @@
Unserialize GMP instance with internal reference to itself
--FILE--
<?php
$s = 'C:3:"GMP":23:{s:1:"2";a:1:{i:46;r:1;}}';
$s = 'C:3:"GMP":23:{s:1:"2";a:1:{i:46;R:1;}}';
var_dump(unserialize($s));
?>
--EXPECT--

View File

@ -531,7 +531,7 @@ static const func_info_t func_infos[] = {
FN("forward_static_call", UNKNOWN_INFO),
FN("forward_static_call_array", UNKNOWN_INFO),
F1("serialize", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING),
FN("unserialize", UNKNOWN_INFO | MAY_BE_REF),
FN("unserialize", UNKNOWN_INFO),
F0("var_dump", MAY_BE_NULL),
F1("var_export", MAY_BE_NULL | MAY_BE_STRING),
F0("debug_zval_dump", MAY_BE_NULL),

View File

@ -2669,7 +2669,7 @@ ZEND_BEGIN_ARG_INFO(arginfo_serialize, 0)
ZEND_ARG_INFO(0, var)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_unserialize, 0, 1, 1)
ZEND_BEGIN_ARG_INFO_EX(arginfo_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, variable_representation)
ZEND_ARG_INFO(0, allowed_classes)
ZEND_END_ARG_INFO()

View File

@ -1124,6 +1124,13 @@ PHP_FUNCTION(unserialize)
/* Reset to previous allowed_classes in case this is a nested call */
php_var_unserialize_set_allowed_classes(var_hash, prev_class_hash);
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
/* Per calling convention we must not return a reference here, so unwrap. We're doing this at
* the very end, because __wakeup() calls performed during UNSERIALIZE_DESTROY might affect
* the value we unwrap here. This is compatible with behavior in PHP <=7.0. */
if (Z_ISREF_P(return_value)) {
zend_unwrap_reference(return_value);
}
}
/* }}} */