From fe0263f3445ec48bbac56c43720629c9bf4700dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Wed, 17 Sep 2025 19:46:19 +0200 Subject: [PATCH 1/2] uri: Throw `UriError` for unexpected failures (#19850) * uri: Add `UriError` * uri: Throw `UriError` for unexpected failures in uri_parser_rfc3986 This is a follow-up for php/php-src#19779 which updated the error *messages* for the non-syntax errors, but did not update the exception class, still implying it's related to invalid URIs. Given that we don't know ourselves if these are reachable in practice, they are cannot be meaningfully handled by a user of PHP. Thus this should be a `Error` according to our exception policy. * uri: Throw `UriError` when unable to recompose URIs * uri: Throw `UriError` when unable to read component * NEWS --- NEWS | 2 ++ ext/uri/php_uri.c | 4 +++- ext/uri/php_uri.stub.php | 5 +++++ ext/uri/php_uri_arginfo.h | 12 +++++++++++- ext/uri/php_uri_common.c | 2 +- ext/uri/php_uri_common.h | 1 + ext/uri/uri_parser_rfc3986.c | 18 +++++++++--------- 7 files changed, 32 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index 42846ab7c5205..e2d6d9688b552 100644 --- a/NEWS +++ b/NEWS @@ -46,6 +46,8 @@ PHP NEWS (nielsdos) . Prevent modifying Uri\WhatWg\Url and Uri\Rfc3986\Uri objects by manually calling __construct() or __unserialize(). (timwolla) + . Add new Uri\UriError exception that is thrown for internal error + conditions. (timwolla) . Further clean up the internal API. (timwolla) - Windows: diff --git a/ext/uri/php_uri.c b/ext/uri/php_uri.c index e5436d7f1e369..c36d5f9b43c42 100644 --- a/ext/uri/php_uri.c +++ b/ext/uri/php_uri.c @@ -38,6 +38,7 @@ zend_class_entry *uri_whatwg_url_ce; zend_object_handlers uri_whatwg_uri_object_handlers; zend_class_entry *uri_comparison_mode_ce; zend_class_entry *uri_exception_ce; +zend_class_entry *uri_error_ce; zend_class_entry *uri_invalid_uri_exception_ce; zend_class_entry *uri_whatwg_invalid_url_exception_ce; zend_class_entry *uri_whatwg_url_validation_error_type_ce; @@ -675,7 +676,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, withFragment) static void throw_cannot_recompose_uri_to_string(zend_object *object) { - zend_throw_exception_ex(NULL, 0, "Cannot recompose %s to a string", ZSTR_VAL(object->ce->name)); + zend_throw_exception_ex(uri_error_ce, 0, "Cannot recompose %s to a string", ZSTR_VAL(object->ce->name)); } static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, zend_object *that_object, zend_object *comparison_mode) @@ -1105,6 +1106,7 @@ static PHP_MINIT_FUNCTION(uri) uri_comparison_mode_ce = register_class_Uri_UriComparisonMode(); uri_exception_ce = register_class_Uri_UriException(zend_ce_exception); + uri_error_ce = register_class_Uri_UriError(zend_ce_error); uri_invalid_uri_exception_ce = register_class_Uri_InvalidUriException(uri_exception_ce); uri_whatwg_invalid_url_exception_ce = register_class_Uri_WhatWg_InvalidUrlException(uri_invalid_uri_exception_ce); uri_whatwg_url_validation_error_ce = register_class_Uri_WhatWg_UrlValidationError(); diff --git a/ext/uri/php_uri.stub.php b/ext/uri/php_uri.stub.php index b4063bee8f596..9f12fbb1c0701 100644 --- a/ext/uri/php_uri.stub.php +++ b/ext/uri/php_uri.stub.php @@ -8,6 +8,11 @@ class UriException extends \Exception { } + /** @strict-properties */ + class UriError extends \Error + { + } + /** @strict-properties */ class InvalidUriException extends \Uri\UriException { diff --git a/ext/uri/php_uri_arginfo.h b/ext/uri/php_uri_arginfo.h index 12a498357ea28..602e996b1a226 100644 --- a/ext/uri/php_uri_arginfo.h +++ b/ext/uri/php_uri_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: bf37e0babfcc453ab0c75d0e87e142dfa3b5e61e */ + * Stub hash: f3c524798d1933a400cc9377cfbfdcbaf77b87f0 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_parse, 0, 1, IS_STATIC, 1) ZEND_ARG_TYPE_INFO(0, uri, IS_STRING, 0) @@ -321,6 +321,16 @@ static zend_class_entry *register_class_Uri_UriException(zend_class_entry *class return class_entry; } +static zend_class_entry *register_class_Uri_UriError(zend_class_entry *class_entry_Error) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Uri", "UriError", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, ZEND_ACC_NO_DYNAMIC_PROPERTIES); + + return class_entry; +} + static zend_class_entry *register_class_Uri_InvalidUriException(zend_class_entry *class_entry_Uri_UriException) { zend_class_entry ce, *class_entry; diff --git a/ext/uri/php_uri_common.c b/ext/uri/php_uri_common.c index efb7688a94502..c4ee94b4d5b98 100644 --- a/ext/uri/php_uri_common.c +++ b/ext/uri/php_uri_common.c @@ -52,7 +52,7 @@ void uri_read_component(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name prop const php_uri_property_handler *property_handler = php_uri_parser_property_handler_by_name(internal_uri->parser, property_name); if (UNEXPECTED(property_handler->read(internal_uri->uri, component_read_mode, return_value) == FAILURE)) { - zend_throw_error(NULL, "The %s component cannot be retrieved", ZSTR_VAL(get_known_string_by_property_name(property_name))); + zend_throw_exception_ex(uri_error_ce, 0, "The %s component cannot be retrieved", ZSTR_VAL(get_known_string_by_property_name(property_name))); RETURN_THROWS(); } } diff --git a/ext/uri/php_uri_common.h b/ext/uri/php_uri_common.h index f061db6f981b1..ba5b0b2d7ee46 100644 --- a/ext/uri/php_uri_common.h +++ b/ext/uri/php_uri_common.h @@ -23,6 +23,7 @@ extern zend_class_entry *uri_whatwg_url_ce; extern zend_object_handlers uri_whatwg_uri_object_handlers; extern zend_class_entry *uri_comparison_mode_ce; extern zend_class_entry *uri_exception_ce; +extern zend_class_entry *uri_error_ce; extern zend_class_entry *uri_invalid_uri_exception_ce; extern zend_class_entry *uri_whatwg_invalid_url_exception_ce; extern zend_class_entry *uri_whatwg_url_validation_error_type_ce; diff --git a/ext/uri/uri_parser_rfc3986.c b/ext/uri/uri_parser_rfc3986.c index 583d3b9f5e0ae..c60c86efbfc36 100644 --- a/ext/uri/uri_parser_rfc3986.c +++ b/ext/uri/uri_parser_rfc3986.c @@ -136,7 +136,7 @@ static zend_result php_uri_parser_rfc3986_scheme_write(void *uri, zval *value, z return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to update the scheme", 0); + zend_throw_exception(uri_error_ce, "Failed to update the scheme", 0); return FAILURE; } } @@ -176,7 +176,7 @@ zend_result php_uri_parser_rfc3986_userinfo_write(void *uri, zval *value, zval * return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to update the userinfo", 0); + zend_throw_exception(uri_error_ce, "Failed to update the userinfo", 0); return FAILURE; } } @@ -271,7 +271,7 @@ static zend_result php_uri_parser_rfc3986_host_write(void *uri, zval *value, zva return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to update the host", 0); + zend_throw_exception(uri_error_ce, "Failed to update the host", 0); return FAILURE; } } @@ -331,7 +331,7 @@ static zend_result php_uri_parser_rfc3986_port_write(void *uri, zval *value, zva return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to update the port", 0); + zend_throw_exception(uri_error_ce, "Failed to update the port", 0); return FAILURE; } } @@ -383,7 +383,7 @@ static zend_result php_uri_parser_rfc3986_path_write(void *uri, zval *value, zva return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to update the path", 0); + zend_throw_exception(uri_error_ce, "Failed to update the path", 0); return FAILURE; } } @@ -420,7 +420,7 @@ static zend_result php_uri_parser_rfc3986_query_write(void *uri, zval *value, zv return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to update the query", 0); + zend_throw_exception(uri_error_ce, "Failed to update the query", 0); return FAILURE; } } @@ -457,7 +457,7 @@ static zend_result php_uri_parser_rfc3986_fragment_write(void *uri, zval *value, return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to update the fragment", 0); + zend_throw_exception(uri_error_ce, "Failed to update the fragment", 0); return FAILURE; } } @@ -484,7 +484,7 @@ php_uri_parser_rfc3986_uris *php_uri_parser_rfc3986_parse_ex(const char *uri_str break; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to parse the specified URI", 0); + zend_throw_exception(uri_error_ce, "Failed to parse the specified URI", 0); break; } } @@ -506,7 +506,7 @@ php_uri_parser_rfc3986_uris *php_uri_parser_rfc3986_parse_ex(const char *uri_str break; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to resolve the specified URI against the base URI", 0); + zend_throw_exception(uri_error_ce, "Failed to resolve the specified URI against the base URI", 0); break; } } From c89359164b59d2dcf03754c297d545bba2bdc0a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Wed, 17 Sep 2025 19:48:18 +0200 Subject: [PATCH 2/2] main: Disable `$_SERVER` JIT when `register_argc_argv=1` (#19833) Fixes php/php-src#19823 and makes the deprecation more reliable by triggering even when `$_SERVER` is not accessed. --- NEWS | 2 ++ main/php_variables.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index e2d6d9688b552..cdabc59a8f836 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,8 @@ PHP NEWS . Fixed hard_timeout with --enable-zend-max-execution-timers. (Appla) . Fixed bug GH-19839 (Incorrect HASH_FLAG_HAS_EMPTY_IND flag on userland array). (ilutov) + . Fixed bug GH-19823 (register_argc_argv deprecation emitted twice when + using OPcache). (timwolla) - Curl: . Fix cloning of CURLOPT_POSTFIELDS when using the clone operator instead diff --git a/main/php_variables.c b/main/php_variables.c index 707564e680239..e0fe979d94d9b 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -975,7 +975,7 @@ void php_startup_auto_globals(void) zend_register_auto_global(zend_string_init_interned("_GET", sizeof("_GET")-1, 1), 0, php_auto_globals_create_get); zend_register_auto_global(zend_string_init_interned("_POST", sizeof("_POST")-1, 1), 0, php_auto_globals_create_post); zend_register_auto_global(zend_string_init_interned("_COOKIE", sizeof("_COOKIE")-1, 1), 0, php_auto_globals_create_cookie); - zend_register_auto_global(ZSTR_KNOWN(ZEND_STR_AUTOGLOBAL_SERVER), PG(auto_globals_jit), php_auto_globals_create_server); + zend_register_auto_global(ZSTR_KNOWN(ZEND_STR_AUTOGLOBAL_SERVER), PG(auto_globals_jit) && (SG(request_info).argc || !PG(register_argc_argv)), php_auto_globals_create_server); zend_register_auto_global(ZSTR_KNOWN(ZEND_STR_AUTOGLOBAL_ENV), PG(auto_globals_jit), php_auto_globals_create_env); zend_register_auto_global(ZSTR_KNOWN(ZEND_STR_AUTOGLOBAL_REQUEST), PG(auto_globals_jit), php_auto_globals_create_request); zend_register_auto_global(zend_string_init_interned("_FILES", sizeof("_FILES")-1, 1), 0, php_auto_globals_create_files);