diff --git a/NEWS b/NEWS index 05bdd1b35ff7..afb45fca45ca 100644 --- a/NEWS +++ b/NEWS @@ -93,6 +93,8 @@ PHP NEWS . Fix persistent free of non-persistent connect_attr key (David Carlier). - Opcache: + . Fixed bug GH-21972 (Corrupted variable type when a typed by-value return + contains a reference wrapper). (Weilin Du) . Fixed tracing JIT crash when a VM interrupt is handled during an observed user function call. (Levi Morrison) . Fixed bug GH-22004 (Assertion failure at ext/opcache/jit/zend_jit_trace.c). diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 34906e1bfcca..c46b17101546 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4387,7 +4387,7 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV ZVAL_DEREF(retval_ptr); } - if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) { ZEND_VM_NEXT_OPCODE(); } @@ -4417,6 +4417,9 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV } retval_ptr = retval_ref; } + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + ZEND_VM_NEXT_OPCODE(); + } } SAVE_OPLINE(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index d4b2aff1907b..f4f35ce2a8a9 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -10772,7 +10772,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYP ZVAL_DEREF(retval_ptr); } - if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) { ZEND_VM_NEXT_OPCODE(); } @@ -10802,6 +10802,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYP } retval_ptr = retval_ref; } + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + ZEND_VM_NEXT_OPCODE(); + } } SAVE_OPLINE(); @@ -21517,7 +21520,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN ZVAL_DEREF(retval_ptr); } - if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) { ZEND_VM_NEXT_OPCODE(); } @@ -21547,6 +21550,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN } retval_ptr = retval_ref; } + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + ZEND_VM_NEXT_OPCODE(); + } } SAVE_OPLINE(); @@ -30016,7 +30022,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN ZVAL_DEREF(retval_ptr); } - if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) { ZEND_VM_NEXT_OPCODE(); } @@ -30046,6 +30052,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN } retval_ptr = retval_ref; } + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + ZEND_VM_NEXT_OPCODE(); + } } SAVE_OPLINE(); @@ -37830,7 +37839,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED ZVAL_DEREF(retval_ptr); } - if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) { ZEND_VM_NEXT_OPCODE(); } @@ -37860,6 +37869,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED } retval_ptr = retval_ref; } + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + ZEND_VM_NEXT_OPCODE(); + } } SAVE_OPLINE(); @@ -50642,7 +50654,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU ZVAL_DEREF(retval_ptr); } - if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) { ZEND_VM_NEXT_OPCODE(); } @@ -50672,6 +50684,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU } retval_ptr = retval_ref; } + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + ZEND_VM_NEXT_OPCODE(); + } } SAVE_OPLINE(); diff --git a/ext/opcache/tests/opt/gh21972.phpt b/ext/opcache/tests/opt/gh21972.phpt new file mode 100644 index 000000000000..f34f9b45ccf2 --- /dev/null +++ b/ext/opcache/tests/opt/gh21972.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-21972: Typed by-value return must not leak reference wrapper +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--EXTENSIONS-- +opcache +--FILE-- + +--EXPECT-- +string(6) "string" +string(5) "false" +string(5) "false" diff --git a/ext/sockets/conversions.c b/ext/sockets/conversions.c index a419a20c873c..eb4e58b3988e 100644 --- a/ext/sockets/conversions.c +++ b/ext/sockets/conversions.c @@ -1385,7 +1385,7 @@ static void from_zval_write_fd_array_aux(zval *elem, unsigned i, void **args, se return; } - iarr[i] = sock->bsd_socket; + iarr[i - 1] = sock->bsd_socket; return; } diff --git a/ext/sockets/tests/socket_cmsg_rights.phpt b/ext/sockets/tests/socket_cmsg_rights.phpt index 1794eaf767ac..8bfbcd57157f 100644 --- a/ext/sockets/tests/socket_cmsg_rights.phpt +++ b/ext/sockets/tests/socket_cmsg_rights.phpt @@ -58,7 +58,7 @@ if ($data["control"]) { if ($control["level"] == SOL_SOCKET && $control["type"] == SCM_RIGHTS) { foreach ($control["data"] as $resource) { - if (!is_resource($resource)) { + if (!is_resource($resource) && !($resource instanceof Socket)) { echo "FAIL RES\n"; var_dump($data); exit; diff --git a/ext/sockets/tests/socket_sendmsg_scm_rights_object.phpt b/ext/sockets/tests/socket_sendmsg_scm_rights_object.phpt new file mode 100644 index 000000000000..6f9868038ebd --- /dev/null +++ b/ext/sockets/tests/socket_sendmsg_scm_rights_object.phpt @@ -0,0 +1,65 @@ +--TEST-- +socket_sendmsg(): SCM_RIGHTS transfers a Socket object with the correct fd +--EXTENSIONS-- +sockets +--SKIPIF-- + +--FILE-- + ['x'], + 'control' => [[ + 'level' => SOL_SOCKET, + 'type' => SCM_RIGHTS, + 'data' => [$payload], + ]], +], 0); + +$data = [ + 'name' => [], + 'buffer_size' => 64, + 'controllen' => socket_cmsg_space(SOL_SOCKET, SCM_RIGHTS, 1), +]; +socket_recvmsg($recv, $data, 0); + +$got = $data['control'][0]['data'][0]; +var_dump($got instanceof Socket); +socket_getsockname($got, $addr); +var_dump($addr === $ppath); +?> +--CLEAN-- + +--EXPECT-- +bool(true) +bool(true)