Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ PHP NEWS
. Fixed bug GH-23477 (Memory leak on duplicate native Phar manifest entries).
(Weilin Du)

- Sockets:
. Fixed socket_set_option() with SO_ATTACH_REUSEPORT_CBPF and a zero value,
which detached the classic BPF filter instead of the reuseport program.
(David Carlier)

- Standard:
. Fixed a segfault when a stream filter callback unsets StreamBucket::$data
before re-attaching the bucket. (iliaal)
Expand Down
17 changes: 14 additions & 3 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,16 @@ PHP 8.6 UPGRADE NOTES
rules" message. Code that compares the exact message may need to be
updated.

- Sockets:
. socket_set_option() with SO_ATTACH_REUSEPORT_CBPF now requires an int
$value and a $level of SOL_SOCKET. Any other value type throws a TypeError
instead of being coerced, and any other level raises a warning and returns
false.
. socket_set_option() with SO_ATTACH_REUSEPORT_CBPF and a $value of 0 now
detaches the reuseport filter through SO_DETACH_REUSEPORT_BPF. It
previously used SO_DETACH_BPF, an alias of SO_DETACH_FILTER, which left the
reuseport program attached.

- Sodium:
. The password-hashing functions sodium_crypto_pwhash(),
sodium_crypto_pwhash_str(),
Expand Down Expand Up @@ -484,10 +494,10 @@ PHP 8.6 UPGRADE NOTES
RFC: https://wiki.php.net/rfc/uri_followup#uri_type_detection
. Added Uri\Rfc3986\Uri::getHostType() and Uri\WhatWg\Url::getHostType().
RFC: https://wiki.php.net/rfc/uri_followup#host_type_detection
. Added Uri\Rfc3986\UriBuilder.
RFC: https://wiki.php.net/rfc/uri_followup#uri_building
. Added Uri\WhatWg\UrlBuilder.
. Added Uri\Rfc3986\UriBuilder and Uri\WhatWg\UrlBuilder.
RFC: https://wiki.php.net/rfc/uri_followup#uri_building
. Added Uri\url_percent_encode().
RFC: https://wiki.php.net/rfc/uri_followup#percent-encoding_support

========================================
3. Changes in SAPI modules
Expand Down Expand Up @@ -860,6 +870,7 @@ PHP 8.6 UPGRADE NOTES
. EAI_ALLDONE.
. EAI_INTR.
. EAI_IDN_ENCODE.
. SO_DETACH_REUSEPORT_BPF (Linux only).

- Standard:
. ARRAY_FILTER_USE_VALUE.
Expand Down
6 changes: 5 additions & 1 deletion ext/soap/soap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1583,7 +1583,11 @@ PHP_METHOD(SoapServer, handle)

/* If new session or something weird happned */
if (soap_obj == NULL) {
object_init_ex(&tmp_soap, service->soap_class.ce);
if (UNEXPECTED(object_init_ex(&tmp_soap, service->soap_class.ce) != SUCCESS)) {
php_output_discard();
_soap_server_exception(service, function, ZEND_THIS);
goto fail;
}

/* Call constructor */
if (service->soap_class.ce->constructor) {
Expand Down
28 changes: 28 additions & 0 deletions ext/soap/tests/gh23447.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
--TEST--
GH-23447 (Segfault when a class passed to SoapServer::setClass() fails to initialize)
--EXTENSIONS--
soap
--CREDITS--
Lu Maltsis (@lmaltsis)
--FILE--
<?php
class foo {
private $broken = undefinedConstant;
}

$server = new SoapServer(null, ['uri' => 'http://testuri.org']);
$server->setClass('foo');

$server->handle(<<<'XML'
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body><anything/></SOAP-ENV:Body>
</SOAP-ENV:Envelope>
XML);

echo "ok\n";
?>
--EXPECT--
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>Undefined constant "undefinedConstant"</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
ok
15 changes: 14 additions & 1 deletion ext/sockets/sockets.c
Original file line number Diff line number Diff line change
Expand Up @@ -2341,13 +2341,26 @@ PHP_FUNCTION(socket_set_option)

#ifdef SO_ATTACH_REUSEPORT_CBPF
case SO_ATTACH_REUSEPORT_CBPF: {
if (level != SOL_SOCKET) {
php_error_docref(NULL, E_WARNING, "Invalid level");
RETURN_FALSE;
}
if (Z_TYPE_P(arg4) != IS_LONG) {
zend_argument_type_error(4, "must be of type int when argument #3 ($option) is SO_ATTACH_REUSEPORT_CBPF, %s given", zend_zval_value_name(arg4));
RETURN_THROWS();
}
zend_long cbpf_val = zval_get_long(arg4);

if (!cbpf_val) {
#ifdef SO_DETACH_REUSEPORT_BPF
ov = 1;
optlen = sizeof(ov);
opt_ptr = &ov;
optname = SO_DETACH_BPF;
optname = SO_DETACH_REUSEPORT_BPF;
#else
php_error_docref(NULL, E_WARNING, "Detaching a reuseport CBPF filter is unsupported");
RETURN_FALSE;
#endif
} else {
uint32_t k = (uint32_t)cbpf_val;

Expand Down
7 changes: 7 additions & 0 deletions ext/sockets/sockets.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -1898,6 +1898,13 @@
*/
const SO_ATTACH_REUSEPORT_CBPF = UNKNOWN;
#endif
#if defined(SO_DETACH_REUSEPORT_BPF)
/**
* @var int
* @cvalue SO_DETACH_REUSEPORT_BPF
*/
const SO_DETACH_REUSEPORT_BPF = UNKNOWN;
#endif
#if defined(SO_DETACH_FILTER)
/**
* @var int
Expand Down
5 changes: 4 additions & 1 deletion ext/sockets/sockets_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions ext/sockets/tests/socket_reuseport_cbpf.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,18 @@ if (!$socket) {
var_dump(socket_set_option( $socket, SOL_SOCKET, SO_REUSEADDR, true));
var_dump(socket_set_option( $socket, SOL_SOCKET, SO_REUSEPORT, true));
try {
socket_set_option( $socket, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, array());
socket_set_option( $socket, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, []);
} catch (\TypeError $e) {
echo $e->getMessage() . PHP_EOL;
echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump(socket_set_option( $socket, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, SKF_AD_CPU));
var_dump(socket_bind($socket, '0.0.0.0'));
socket_listen($socket);
socket_close($socket);
?>
--EXPECTF--
--EXPECT--
bool(true)
bool(true)

Warning: socket_set_option(): Unable to set socket option [2]: No such file or directory in %s on line %d
TypeError: socket_set_option(): Argument #4 ($value) must be of type int when argument #3 ($option) is SO_ATTACH_REUSEPORT_CBPF, array given
bool(true)
bool(true)
38 changes: 38 additions & 0 deletions ext/sockets/tests/socket_reuseport_cbpf_detach.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
--TEST--
socket_set_option() attach/detach round trip for reuseport CBPF filters
--EXTENSIONS--
sockets
--SKIPIF--
<?php
if (!defined("SO_ATTACH_REUSEPORT_CBPF") || !defined("SO_DETACH_REUSEPORT_BPF")) {
die('SKIP on platforms not supporting reuseport CBPF filters');
}
?>
--FILE--
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

var_dump(socket_set_option($socket, SOL_SOCKET, SO_REUSEPORT, true));
var_dump(socket_bind($socket, '127.0.0.1', 0));
var_dump(socket_listen($socket));

var_dump(socket_set_option($socket, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, SKF_AD_CPU));
var_dump(socket_set_option($socket, SOL_SOCKET, SO_DETACH_REUSEPORT_BPF, 1));
var_dump(socket_set_option($socket, SOL_SOCKET, SO_DETACH_REUSEPORT_BPF, 1));

var_dump(socket_set_option($socket, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, SKF_AD_QUEUE));
var_dump(socket_set_option($socket, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, 0));

socket_close($socket);
?>
--EXPECTF--
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)

Warning: socket_set_option(): Unable to set socket option [%d]: %s in %s on line %d
bool(false)
bool(true)
bool(true)
69 changes: 63 additions & 6 deletions ext/uri/php_uri.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ zend_class_entry *php_uri_ce_rfc3986_uri_type;
zend_class_entry *php_uri_ce_rfc3986_uri_host_type;
zend_class_entry *php_uri_ce_whatwg_url_builder;
zend_class_entry *php_uri_ce_whatwg_url;
zend_class_entry *php_uri_ce_whatwg_url_percent_encoding_mode;
zend_class_entry *php_uri_ce_comparison_mode;
zend_class_entry *php_uri_ce_exception;
zend_class_entry *php_uri_ce_error;
Expand Down Expand Up @@ -1073,6 +1074,60 @@ PHP_METHOD(Uri_WhatWg_Url, __debugInfo)
RETURN_ARR(uri_get_debug_properties(uri_object));
}

PHP_FUNCTION(Uri_WhatWg_url_percent_encode)
{
zend_string *input;
zend_enum_Uri_WhatWg_UrlPercentEncodingMode mode;

ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_STR(input)
Z_PARAM_ENUM(mode, php_uri_ce_whatwg_url_percent_encoding_mode)
ZEND_PARSE_PARAMETERS_END();

zend_string *str;

switch (mode) {
case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_Username:
ZEND_FALLTHROUGH;
case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_Password:
str = php_uri_parser_whatwg_percent_encode_userinfo_component(ZSTR_VAL(input), ZSTR_LEN(input));
break;
case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_OpaqueHost:
str = php_uri_parser_whatwg_percent_encode_opaque_host_component(ZSTR_VAL(input), ZSTR_LEN(input));
break;
case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_Path:
str = php_uri_parser_whatwg_percent_encode_path_component(ZSTR_VAL(input), ZSTR_LEN(input));
break;
case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_OpaquePath:
str = php_uri_parser_whatwg_percent_encode_opaque_path_component(ZSTR_VAL(input), ZSTR_LEN(input));
break;
case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_PathSegment:
str = php_uri_parser_whatwg_percent_encode_path_segment_component(ZSTR_VAL(input), ZSTR_LEN(input));
break;
case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_Query:
str = php_uri_parser_whatwg_percent_encode_query_component(ZSTR_VAL(input), ZSTR_LEN(input));
break;
case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_SpecialQuery:
str = php_uri_parser_whatwg_percent_encode_special_query_component(ZSTR_VAL(input), ZSTR_LEN(input));
break;
case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_FormQuery:
str = php_uri_parser_whatwg_percent_encode_form_query_component(ZSTR_VAL(input), ZSTR_LEN(input));
break;
case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_Fragment:
str = php_uri_parser_whatwg_percent_encode_fragment_component(ZSTR_VAL(input), ZSTR_LEN(input));
break;
default: ZEND_UNREACHABLE();
}

/* This should be unreachable in practice, as str is null only due to memory errors. */
if (str == NULL) {
zend_throw_exception(php_uri_ce_error, "Cannot percent-encode input", 0);
RETURN_THROWS();
}

RETURN_NEW_STR(str);
}

PHP_METHOD(Uri_Rfc3986_UriBuilder, reset)
{
ZEND_PARSE_PARAMETERS_NONE();
Expand Down Expand Up @@ -1481,6 +1536,8 @@ static PHP_MINIT_FUNCTION(uri)
object_handlers_whatwg_uri.free_obj = php_uri_object_handler_free;
object_handlers_whatwg_uri.clone_obj = php_uri_object_handler_clone;

php_uri_ce_whatwg_url_percent_encoding_mode = register_class_Uri_WhatWg_UrlPercentEncodingMode();

php_uri_ce_comparison_mode = register_class_Uri_UriComparisonMode();
php_uri_ce_exception = register_class_Uri_UriException(zend_ce_exception);
php_uri_ce_error = register_class_Uri_UriError(zend_ce_error);
Expand Down Expand Up @@ -1548,14 +1605,14 @@ ZEND_MODULE_POST_ZEND_DEACTIVATE_D(uri)
zend_module_entry uri_module_entry = {
STANDARD_MODULE_HEADER_EX, NULL,
uri_deps,
"uri", /* Extension name */
NULL, /* zend_function_entry */
"uri", /* Extension name */
ext_functions, /* zend_function_entry */
PHP_MINIT(uri), /* PHP_MINIT - Module initialization */
PHP_MSHUTDOWN(uri), /* PHP_MSHUTDOWN - Module shutdown */
PHP_MSHUTDOWN(uri), /* PHP_MSHUTDOWN - Module shutdown */
PHP_RINIT(uri), /* PHP_RINIT - Request initialization */
NULL, /* PHP_RSHUTDOWN - Request shutdown */
PHP_MINFO(uri), /* PHP_MINFO - Module info */
PHP_VERSION, /* Version */
NULL, /* PHP_RSHUTDOWN - Request shutdown */
PHP_MINFO(uri), /* PHP_MINFO - Module info */
PHP_VERSION, /* Version */
NO_MODULE_GLOBALS,
ZEND_MODULE_POST_ZEND_DEACTIVATE_N(uri),
STANDARD_MODULE_PROPERTIES_EX
Expand Down
16 changes: 16 additions & 0 deletions ext/uri/php_uri.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -317,4 +317,20 @@ public function __unserialize(array $data): void {}

public function __debugInfo(): array {}
}

enum UrlPercentEncodingMode
{
case Username;
case Password;
case OpaqueHost;
case Path;
case OpaquePath;
case PathSegment;
case Query;
case SpecialQuery;
case FormQuery;
case Fragment;
}

function url_percent_encode(string $input, \Uri\WhatWg\UrlPercentEncodingMode $mode): string {}
}
40 changes: 39 additions & 1 deletion ext/uri/php_uri_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading