diff --git a/NEWS b/NEWS index 9159e3ecfdbc..a56e0efdda72 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,8 @@ PHP NEWS . Fixed bug GH-22265 (Another tailcall vm_interrupt bug). (Levi Morrison) . Fixed bug GH-20469 (Unsafe inheritance cache replay with reentrant autoloading). (Levi Morrison) + . Fixed bug GH-21972 (Corrupted variable type when a typed by-value return + contains a reference wrapper). (Weilin Du) - Phar: . Fixed a bypass of the magic ".phar" directory protection in diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index fdfe48fc8421..90a666ab71e7 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4454,7 +4454,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(); } @@ -4483,6 +4483,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 0faa84444be3..a7ecbe68ae81 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -11115,7 +11115,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ 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(); } @@ -11144,6 +11144,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ } retval_ptr = retval_ref; } + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + ZEND_VM_NEXT_OPCODE(); + } } SAVE_OPLINE(); @@ -22095,7 +22098,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN 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(); } @@ -22124,6 +22127,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN } retval_ptr = retval_ref; } + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + ZEND_VM_NEXT_OPCODE(); + } } SAVE_OPLINE(); @@ -30741,7 +30747,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN 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(); } @@ -30770,6 +30776,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN } retval_ptr = retval_ref; } + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + ZEND_VM_NEXT_OPCODE(); + } } SAVE_OPLINE(); @@ -38745,7 +38754,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN 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(); } @@ -38774,6 +38783,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN } retval_ptr = retval_ref; } + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + ZEND_VM_NEXT_OPCODE(); + } } SAVE_OPLINE(); @@ -51891,7 +51903,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN 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(); } @@ -51920,6 +51932,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN } 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/soap/php_http.c b/ext/soap/php_http.c index 944b033363c6..c7f3732f2987 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -1162,12 +1162,12 @@ int make_http_soap_request( zend_string_release_ex(http_headers, 0); zend_string_release_ex(http_body, 0); if (new_uri->scheme == NULL && new_uri->path != NULL) { - new_uri->scheme = new_uri->scheme ? zend_string_copy(new_uri->scheme) : NULL; - new_uri->host = new_uri->host ? zend_string_copy(new_uri->host) : NULL; - new_uri->port = new_uri->port; + new_uri->scheme = uri->scheme ? zend_string_copy(uri->scheme) : NULL; + new_uri->host = uri->host ? zend_string_copy(uri->host) : NULL; + new_uri->port = uri->port; if (new_uri->path && ZSTR_VAL(new_uri->path)[0] != '/') { - if (new_uri->path) { - char *t = ZSTR_VAL(new_uri->path); + if (uri->path) { + char *t = ZSTR_VAL(uri->path); char *p = strrchr(t, '/'); if (p) { zend_string *s = zend_string_alloc((p - t) + ZSTR_LEN(new_uri->path) + 2, 0); diff --git a/ext/soap/tests/bugs/relative_redirect.phpt b/ext/soap/tests/bugs/relative_redirect.phpt new file mode 100644 index 000000000000..774e7cbd98d7 --- /dev/null +++ b/ext/soap/tests/bugs/relative_redirect.phpt @@ -0,0 +1,49 @@ +--TEST-- +SOAP client follows a redirect with a scheme-less (relative) Location +--EXTENSIONS-- +soap +--SKIPIF-- + +--FILE-- +', + '', + 'ok', + ''; +} else { + http_response_code(302); + header("Location: /redirected"); +} +PHP; + +php_cli_server_start($code, null, $args); + +$client = new SoapClient(null, [ + 'location' => 'http://' . PHP_CLI_SERVER_ADDRESS . '/start', + 'uri' => 'test-uri', +]); + +try { + $client->__soapCall("foo", []); + echo "redirect followed\n"; +} catch (SoapFault $e) { + echo "SoapFault: " . $e->getMessage() . "\n"; +} +?> +--EXPECT-- +redirect followed