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
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ PHP NEWS
2GB on some platforms, e.g. Windows. (Sjoerd Langkemper)

- DOM:
. Fixed a typo in the DOMException message for INUSE_ATTRIBUTE_ERR.
(Weilin Du)
. Fixed bug GH-22624 (use-after-free via DOMNameSpaceNode after
DOMDocument::xinclude()). (David Carlier)
. Fixed a use-after-free when cloning a DOMNameSpaceNode after
Expand Down
2 changes: 2 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,8 @@ PHP 8.6 UPGRADE NOTES
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.
RFC: https://wiki.php.net/rfc/uri_followup#uri_building

========================================
3. Changes in SAPI modules
Expand Down
2 changes: 1 addition & 1 deletion ext/dom/domexception.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void php_dom_throw_error(dom_exception_code error_code, bool strict_error)
error_message = "Not Supported Error";
break;
case INUSE_ATTRIBUTE_ERR:
error_message = "Inuse Attribute Error";
error_message = "In Use Attribute Error";
break;
case INVALID_STATE_ERR:
error_message = "Invalid State Error";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ echo $dom1->saveHtml(), "\n";

?>
--EXPECT--
Inuse Attribute Error
In Use Attribute Error
<container my-attribute="1"><element></element></container>
12 changes: 4 additions & 8 deletions ext/opcache/zend_shared_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,11 @@
+----------------------------------------------------------------------+
*/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#if defined(__linux__) && defined(HAVE_MEMFD_CREATE)
# ifndef _GNU_SOURCE
# define _GNU_SOURCE
#if defined(__linux__)
# include <php_config.h>
# if defined(HAVE_MEMFD_CREATE)
# include <sys/mman.h>
# endif
# include <sys/mman.h>
#endif

#include <errno.h>
Expand Down
44 changes: 36 additions & 8 deletions ext/snmp/snmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1061,20 +1061,48 @@ static ZEND_ATTRIBUTE_NONNULL bool snmp_session_set_sec_protocol(struct snmp_ses
s->securityPrivProtoLen = USM_PRIV_PROTO_AES_LEN;
return true;
}

# ifdef NETSNMP_DRAFT_BLUMENTHAL_AES_04
if (zend_string_equals_literal_ci(prot, "AES192")) {
s->securityPrivProto = usmAES192PrivProtocol;
s->securityPrivProtoLen = OID_LENGTH(usmAES192PrivProtocol);
return true;
}

if (zend_string_equals_literal_ci(prot, "AES256")) {
s->securityPrivProto = usmAES256PrivProtocol;
s->securityPrivProtoLen = OID_LENGTH(usmAES256PrivProtocol);
return true;
}

if (zend_string_equals_literal_ci(prot, "AES192C")) {
s->securityPrivProto = usmAES192CiscoPrivProtocol;
s->securityPrivProtoLen = OID_LENGTH(usmAES192CiscoPrivProtocol);
return true;
}

if (zend_string_equals_literal_ci(prot, "AES256C")) {
s->securityPrivProto = usmAES256CiscoPrivProtocol;
s->securityPrivProtoLen = OID_LENGTH(usmAES256CiscoPrivProtocol);
return true;
}
# endif
#endif

#ifdef HAVE_AES
# ifndef NETSNMP_DISABLE_DES
zend_value_error("Security protocol must be one of \"DES\", \"AES128\", or \"AES\"");
# else
zend_value_error("Security protocol must be one of \"AES128\", or \"AES\"");
zend_value_error("Security protocol must be one of "
# ifndef NETSNMP_DISABLE_DES
"\"DES\", "
# endif
# ifdef NETSNMP_DRAFT_BLUMENTHAL_AES_04
"\"AES256\", \"AES256C\", \"AES192\", \"AES192C\", "
# endif
#else
# ifndef NETSNMP_DISABLE_DES
"\"AES128\", or \"AES\""
);
#elif !defined(NETSNMP_DISABLE_DES)
zend_value_error("Security protocol must be \"DES\"");
# else
#else
zend_value_error("No security protocol supported");
# endif
#endif
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions ext/snmp/tests/snmp-object-setSecurity_error.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ bool(false)

Warning: SNMP::setSecurity(): Error generating a key for authentication pass phrase 'te': Generic error (The supplied password length is too short.) in %s on line %d
bool(false)
Security protocol must be one of "DES", "AES128", or "AES"
Security protocol must be one of "DES", "AES128", or "AES"
Security protocol must be one of %s
Security protocol must be one of %s

Warning: SNMP::setSecurity(): Error generating a key for privacy pass phrase '': Generic error (The supplied password length is too short.) in %s on line %d
bool(false)
Expand Down
2 changes: 1 addition & 1 deletion ext/snmp/tests/snmp3-error.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ bool(false)

Warning: snmp3_get(): Error generating a key for authentication pass phrase 'te': Generic error (The supplied password length is too short.) in %s on line %d
bool(false)
Security protocol must be one of "DES", "AES128", or "AES"
Security protocol must be one of %s "AES128", or "AES"

Warning: snmp3_get(): Error generating a key for privacy pass phrase '': Generic error (The supplied password length is too short.) in %s on line %d
bool(false)
Expand Down
21 changes: 21 additions & 0 deletions ext/sockets/tests/socket_cmsg_space_num_range_64bit.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--TEST--
socket_cmsg_space() rejects a $num larger than INT_MAX on 64-bit platforms
--EXTENSIONS--
sockets
--SKIPIF--
<?php
if (PHP_INT_SIZE < 8) {
die('skip 64-bit only');
}
?>
--FILE--
<?php
// $num is range checked before the level/type pair is looked up
try {
socket_cmsg_space(SOL_SOCKET, 0, PHP_INT_MAX);
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
ValueError: socket_cmsg_space(): Argument #3 ($num) must be between -2147483648 and 2147483647
9 changes: 0 additions & 9 deletions ext/sockets/tests/socket_cmsg_space_return_type.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,8 @@ try {
echo $e::class, ': ', $e->getMessage(), "\n";
}

// $num overflows int (64-bit only: PHP_INT_MAX > INT_MAX)
if (PHP_INT_SIZE >= 8) {
try {
socket_cmsg_space(SOL_SOCKET, SCM_RIGHTS, PHP_INT_MAX);
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), "\n";
}
}
?>
--EXPECT--
string(3) "int"
ValueError: Pair level 999999 and/or type 999999 is not supported
ValueError: socket_cmsg_space(): Argument #3 ($num) must be greater than or equal to 0
ValueError: socket_cmsg_space(): Argument #3 ($num) must be between -2147483648 and 2147483647
147 changes: 147 additions & 0 deletions ext/uri/php_uri.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ zend_class_entry *php_uri_ce_rfc3986_uri_builder;
zend_class_entry *php_uri_ce_rfc3986_uri;
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_comparison_mode;
zend_class_entry *php_uri_ce_exception;
Expand Down Expand Up @@ -75,6 +76,17 @@ static zend_always_inline zval *php_uri_deref(zval *zv)
#define Z_RFC3986_URI_PROP_QUERY_DEREF_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 5))
#define Z_RFC3986_URI_PROP_FRAGMENT_DEREF_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 6))

#define Z_WHATWG_URL_PROP_SCHEME_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 0)
#define Z_WHATWG_URL_PROP_SCHEME_DEREF_P(zv) php_uri_deref(Z_WHATWG_URL_PROP_SCHEME_P(zv))
#define Z_WHATWG_URL_PROP_USERNAME_DEREF_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 1))
#define Z_WHATWG_URL_PROP_PASSWORD_DEREF_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 2))
#define Z_WHATWG_URL_PROP_HOST_DEREF_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 3))
#define Z_WHATWG_URL_PROP_PORT_DEREF_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 4))
#define Z_WHATWG_URL_PROP_PATH_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 5)
#define Z_WHATWG_URL_PROP_PATH_DEREF_P(zv) php_uri_deref(Z_WHATWG_URL_PROP_PATH_P(zv))
#define Z_WHATWG_URL_PROP_QUERY_DEREF_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 6))
#define Z_WHATWG_URL_PROP_FRAGMENT_DEREF_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 7))

static HashTable *uri_get_debug_properties(php_uri_object *object)
{
const HashTable *std_properties = zend_std_get_properties(&object->std);
Expand Down Expand Up @@ -1244,6 +1256,139 @@ PHP_METHOD(Uri_Rfc3986_UriBuilder, build)
uri_object->uri = uriparser_uris;
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, reset)
{
ZEND_PARSE_PARAMETERS_NONE();

zend_object *object = Z_OBJ_P(ZEND_THIS);
zval *property = object->properties_table;
const zval *end = property + object->ce->default_properties_count;

while (property != end) {
zend_object_dtor_property(object, property);
ZVAL_NULL(property);
property++;
}

ZVAL_EMPTY_STRING(Z_WHATWG_URL_PROP_SCHEME_P(ZEND_THIS));
ZVAL_EMPTY_STRING(Z_WHATWG_URL_PROP_PATH_P(ZEND_THIS));

RETVAL_COPY(ZEND_THIS);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, setScheme)
{
php_uri_builder_set_component_string(
INTERNAL_FUNCTION_PARAM_PASSTHRU,
ZEND_STRL("scheme"),
php_uri_parser_whatwg_validate_scheme
);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, setUsername)
{
php_uri_builder_set_component_string_or_null(
INTERNAL_FUNCTION_PARAM_PASSTHRU,
ZEND_STRL("username"),
php_uri_parser_whatwg_validate_none
);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, setPassword)
{
php_uri_builder_set_component_string_or_null(
INTERNAL_FUNCTION_PARAM_PASSTHRU,
ZEND_STRL("password"),
php_uri_parser_whatwg_validate_none
);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, setHost)
{
php_uri_builder_set_component_string_or_null(
INTERNAL_FUNCTION_PARAM_PASSTHRU,
ZEND_STRL("host"),
php_uri_parser_whatwg_validate_host
);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, setPort)
{
php_uri_builder_set_component_long_or_null(
INTERNAL_FUNCTION_PARAM_PASSTHRU,
ZEND_STRL("port"),
php_uri_parser_whatwg_validate_port
);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, setPath)
{
php_uri_builder_set_component_string(
INTERNAL_FUNCTION_PARAM_PASSTHRU,
ZEND_STRL("path"),
php_uri_parser_whatwg_validate_none
);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, setQuery)
{
php_uri_builder_set_component_string_or_null(
INTERNAL_FUNCTION_PARAM_PASSTHRU,
ZEND_STRL("query"),
php_uri_parser_whatwg_validate_none
);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, setFragment)
{
php_uri_builder_set_component_string_or_null(
INTERNAL_FUNCTION_PARAM_PASSTHRU,
ZEND_STRL("fragment"),
php_uri_parser_whatwg_validate_none
);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, build)
{
zval *base_url_zv = NULL;
zval *errors = NULL;

ZEND_PARSE_PARAMETERS_START(0, 2)
Z_PARAM_OPTIONAL
Z_PARAM_OBJECT_OF_CLASS_OR_NULL(base_url_zv, php_uri_ce_whatwg_url)
Z_PARAM_ZVAL(errors)
ZEND_PARSE_PARAMETERS_END();

const zval *scheme = Z_WHATWG_URL_PROP_SCHEME_DEREF_P(ZEND_THIS);
const zval *username = Z_WHATWG_URL_PROP_USERNAME_DEREF_P(ZEND_THIS);
const zval *password = Z_WHATWG_URL_PROP_PASSWORD_DEREF_P(ZEND_THIS);
const zval *host = Z_WHATWG_URL_PROP_HOST_DEREF_P(ZEND_THIS);
const zval *port = Z_WHATWG_URL_PROP_PORT_DEREF_P(ZEND_THIS);
const zval *path = Z_WHATWG_URL_PROP_PATH_DEREF_P(ZEND_THIS);
const zval *query = Z_WHATWG_URL_PROP_QUERY_DEREF_P(ZEND_THIS);
const zval *fragment = Z_WHATWG_URL_PROP_FRAGMENT_DEREF_P(ZEND_THIS);

lxb_url_t *base_url = NULL;
if (base_url_zv != NULL) {
zend_argument_error(NULL, 1, "is not supported yet, and therefore, null must be passed");
RETURN_THROWS();
base_url = Z_URI_OBJECT_P(base_url_zv)->uri;
}

lxb_url_t *lexbor_url = php_uri_parser_whatwg_build_from_zval(
base_url, scheme, username, password, host, port, path, query, fragment,
errors
);
if (lexbor_url == NULL) {
RETURN_THROWS();
}

object_init_ex(return_value, php_uri_ce_whatwg_url);
php_uri_object *uri_object = Z_URI_OBJECT_P(return_value);
uri_object->parser = &php_uri_parser_whatwg;
uri_object->uri = lexbor_url;
}

PHPAPI php_uri_object *php_uri_object_create(zend_class_entry *class_type, const php_uri_parser *parser)
{
php_uri_object *uri_object = zend_object_alloc(sizeof(*uri_object), class_type);
Expand Down Expand Up @@ -1326,6 +1471,8 @@ static PHP_MINIT_FUNCTION(uri)
php_uri_ce_rfc3986_uri_type = register_class_Uri_Rfc3986_UriType();
php_uri_ce_rfc3986_uri_host_type = register_class_Uri_Rfc3986_UriHostType();

php_uri_ce_whatwg_url_builder = register_class_Uri_WhatWg_UrlBuilder();

php_uri_ce_whatwg_url = register_class_Uri_WhatWg_Url();
php_uri_ce_whatwg_url->create_object = php_uri_object_create_whatwg;
php_uri_ce_whatwg_url->default_object_handlers = &object_handlers_whatwg_uri;
Expand Down
33 changes: 33 additions & 0 deletions ext/uri/php_uri.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,39 @@ enum UrlHostType
case Empty;
}

final class UrlBuilder
{
private string $scheme = "";
private ?string $username = null;
private ?string $password = null;
private ?string $host = null;
private ?int $port = null;
private string $path = "";
private ?string $query = null;
private ?string $fragment = null;

public function reset(): static {}

public function setScheme(string $scheme): static {}

public function setUsername(?string $username): static {}

public function setPassword(#[\SensitiveParameter] ?string $password): static {}

public function setHost(?string $host): static {}

public function setPort(?int $port): static {}

public function setPath(string $path): static {}

public function setQuery(?string $query): static {}

public function setFragment(?string $fragment): static {}

/** @param array $errors */
public function build(?\Uri\WhatWg\Url $baseUrl = null, &$errors = null): \Uri\WhatWg\Url {}
}

/** @strict-properties */
final readonly class Url
{
Expand Down
Loading