From 1ef7abf2bec66320c0d8bf646bad5ff37943e68b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 20 Oct 2025 08:36:41 +0200 Subject: [PATCH 1/5] zend_long: Remove `ZEND_LTOA()` (#20236) * zend_long: Remove `ZEND_LTOA()` This macro is unsafe when the given buffer is too small, since `snprintf()` returns the *required* length of the string if it would fit. Thus unconditionally writing a NUL there might result in a out-of-bounds write. * zend_long: Remove `ZEND_LTOA_BUF_LEN` --- UPGRADING.INTERNALS | 3 +++ Zend/zend_long.h | 15 --------------- ext/standard/hrtime.c | 4 ++-- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index fe2781e025687..d269bd107885e 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -29,6 +29,9 @@ PHP 8.6 INTERNALS UPGRADE NOTES . CHECK_ZVAL_NULL_PATH() and CHECK_NULL_PATH() have been removed, use zend_str_has_nul_byte(Z_STR_P(...)) and zend_char_has_nul_byte() respectively. + . ZEND_LTOA() (and ZEND_LTOA_BUF_LEN) has been removed, as it was + unsafe. Directly use ZEND_LONG_FMT with a function from the + printf family. ======================== 2. Build system changes diff --git a/Zend/zend_long.h b/Zend/zend_long.h index 3796f1c5ababb..fef237701f3bd 100644 --- a/Zend/zend_long.h +++ b/Zend/zend_long.h @@ -51,9 +51,6 @@ typedef int32_t zend_off_t; #endif -/* Conversion macros. */ -#define ZEND_LTOA_BUF_LEN 65 - #ifdef ZEND_ENABLE_ZVAL_LONG64 # define ZEND_LONG_FMT "%" PRId64 # define ZEND_ULONG_FMT "%" PRIu64 @@ -61,7 +58,6 @@ typedef int32_t zend_off_t; # define ZEND_LONG_FMT_SPEC PRId64 # define ZEND_ULONG_FMT_SPEC PRIu64 # ifdef ZEND_WIN32 -# define ZEND_LTOA(i, s, len) _i64toa_s((i), (s), (len), 10) # define ZEND_ATOL(s) _atoi64((s)) # define ZEND_STRTOL(s0, s1, base) _strtoi64((s0), (s1), (base)) # define ZEND_STRTOUL(s0, s1, base) _strtoui64((s0), (s1), (base)) @@ -69,11 +65,6 @@ typedef int32_t zend_off_t; # define ZEND_STRTOUL_PTR _strtoui64 # define ZEND_ABS _abs64 # else -# define ZEND_LTOA(i, s, len) \ - do { \ - int st = snprintf((s), (len), ZEND_LONG_FMT, (i)); \ - (s)[st] = '\0'; \ - } while (0) # define ZEND_ATOL(s) atoll((s)) # define ZEND_STRTOL(s0, s1, base) strtoll((s0), (s1), (base)) # define ZEND_STRTOUL(s0, s1, base) strtoull((s0), (s1), (base)) @@ -90,14 +81,8 @@ typedef int32_t zend_off_t; # define ZEND_LONG_FMT_SPEC PRId32 # define ZEND_ULONG_FMT_SPEC PRIu32 # ifdef ZEND_WIN32 -# define ZEND_LTOA(i, s, len) _ltoa_s((i), (s), (len), 10) # define ZEND_ATOL(s) atol((s)) # else -# define ZEND_LTOA(i, s, len) \ - do { \ - int st = snprintf((s), (len), ZEND_LONG_FMT, (i)); \ - (s)[st] = '\0'; \ - } while (0) # define ZEND_ATOL(s) atol((s)) # endif # define ZEND_STRTOL_PTR strtol diff --git a/ext/standard/hrtime.c b/ext/standard/hrtime.c index 10853493b6390..652531bd3ed4f 100644 --- a/ext/standard/hrtime.c +++ b/ext/standard/hrtime.c @@ -31,9 +31,9 @@ } while (0) #endif #define PHP_RETURN_HRTIME(t) do { \ - char _a[ZEND_LTOA_BUF_LEN]; \ + char _a[65]; \ double _d; \ - HRTIME_U64A(t, _a, ZEND_LTOA_BUF_LEN); \ + HRTIME_U64A(t, _a, sizeof(_a)); \ _d = zend_strtod(_a, NULL); \ RETURN_DOUBLE(_d); \ } while (0) From c03215b62325148fb342cec5fea897bc9e5c202c Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Mon, 20 Oct 2025 03:29:54 -0500 Subject: [PATCH 2/5] Fix missing deprecation message for default case statement followed by semicolon (#20172) Follow-up to GH-19215 --- NEWS | 2 ++ Zend/zend_compile.c | 10 +++++----- tests/lang/033.phpt | 2 ++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index ac12a8098b71b..08daf17d21993 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ PHP NEWS . Fixed bug GH-20113 (Missing new Foo(...) error in constant expressions). (ilutov) . Fixed bug GH-19844 (Don't bail when closing resources on shutdown). (ilutov) + . Fixed deprecation for default case statement followed by semicolon not + being emitted. (theodorejb) - DOM: . Fix getNamedItemNS() incorrect namespace check. (nielsdos) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 8d6ca5a64346d..35228722aa986 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6333,6 +6333,11 @@ static void zend_compile_switch(zend_ast *ast) /* {{{ */ zend_ast *cond_ast = case_ast->child[0]; znode cond_node; + if (case_ast->attr == ZEND_ALT_CASE_SYNTAX) { + CG(zend_lineno) = case_ast->lineno; + zend_error(E_DEPRECATED, "Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead"); + } + if (!cond_ast) { if (has_default_case) { CG(zend_lineno) = case_ast->lineno; @@ -6343,11 +6348,6 @@ static void zend_compile_switch(zend_ast *ast) /* {{{ */ continue; } - if (case_ast->attr == ZEND_ALT_CASE_SYNTAX) { - CG(zend_lineno) = case_ast->lineno; - zend_error(E_DEPRECATED, "Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead"); - } - zend_compile_expr(&cond_node, cond_ast); if (expr_node.op_type == IS_CONST diff --git a/tests/lang/033.phpt b/tests/lang/033.phpt index 41424e40489d6..a8a5837a5501e 100644 --- a/tests/lang/033.phpt +++ b/tests/lang/033.phpt @@ -38,6 +38,8 @@ switch ($a): endswitch; ?> --EXPECTF-- +Deprecated: Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead in %s + Deprecated: Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead in %s If: 11 While: 12346789 From 3ac9efe41536dc41a02e7eee9465051c599327a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 20 Oct 2025 10:30:20 +0200 Subject: [PATCH 3/5] uri: Make uri_parser_rfc3986.h usable for external extensions (#20173) This header could not previously be used due to the `uriparser/Uri.h` include, which is required for the struct definition. Since this struct is considered an implementation detail, we can just make it opaque, preserving type safety, but without allowing external users to touch its contents. Fixes php/php-src#19868. --- NEWS | 2 ++ ext/uri/uri_parser_rfc3986.c | 8 ++++++++ ext/uri/uri_parser_rfc3986.h | 7 +------ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index 08daf17d21993..908838a60dbfb 100644 --- a/NEWS +++ b/NEWS @@ -48,6 +48,8 @@ PHP NEWS - URI: . Fixed bug GH-20088 (Heap-use-after-free in PHP URI WHATWG parser during malformed URL processing). (lexborisov) + . Fixed bug GH-19868 (Unable to use uri_parser_rfc3986.h from external + extensions). (timwolla) 09 Oct 2025, PHP 8.5.0RC2 diff --git a/ext/uri/uri_parser_rfc3986.c b/ext/uri/uri_parser_rfc3986.c index 24dd4e1947b2b..628b73b123f65 100644 --- a/ext/uri/uri_parser_rfc3986.c +++ b/ext/uri/uri_parser_rfc3986.c @@ -20,6 +20,14 @@ #include "Zend/zend_smart_str.h" #include "Zend/zend_exceptions.h" +#include + +struct php_uri_parser_rfc3986_uris { + UriUriA uri; + UriUriA normalized_uri; + bool normalized_uri_initialized; +}; + static void *php_uri_parser_rfc3986_memory_manager_malloc(UriMemoryManager *memory_manager, size_t size) { return emalloc(size); diff --git a/ext/uri/uri_parser_rfc3986.h b/ext/uri/uri_parser_rfc3986.h index bdf792816c29f..b6d42441db7ac 100644 --- a/ext/uri/uri_parser_rfc3986.h +++ b/ext/uri/uri_parser_rfc3986.h @@ -17,16 +17,11 @@ #ifndef PHP_URI_PARSER_RFC3986_H #define PHP_URI_PARSER_RFC3986_H -#include #include "php_uri_common.h" extern const php_uri_parser php_uri_parser_rfc3986; -typedef struct php_uri_parser_rfc3986_uris { - UriUriA uri; - UriUriA normalized_uri; - bool normalized_uri_initialized; -} php_uri_parser_rfc3986_uris; +typedef struct php_uri_parser_rfc3986_uris php_uri_parser_rfc3986_uris; zend_result php_uri_parser_rfc3986_userinfo_read(void *uri, php_uri_component_read_mode read_mode, zval *retval); zend_result php_uri_parser_rfc3986_userinfo_write(void *uri, zval *value, zval *errors); From cea52f796e8339023a452277f7de0cd7e6c2a8eb Mon Sep 17 00:00:00 2001 From: Juliette <663378+jrfnl@users.noreply.github.com> Date: Mon, 20 Oct 2025 10:32:05 +0200 Subject: [PATCH 4/5] PHP 8.5 | UPGRADING: fix entry about new grapheme $locale parameter (#20239) * PHP 8.5 | UPGRADING: fix entry about new grapheme $locale parameter 1. The `grapheme_levenshtein()` function is new to PHP 8.5, so the `$locale` parameter being added does not "change" the function (in the context of changes between PHP 8.4 and 8.5). 2. The `grapheme_substr()` function has also been given the new `$locale` parameter, but was not listed in the changelog entry. Refs: * https://wiki.php.net/rfc/grapheme_levenshtein * https://github.com/php/php-src/commit/bdcea111f30fee395d5830505df5de58598abb5e * https://wiki.php.net/rfc/grapheme_add_locale_for_case_insensitive * https://github.com/php/php-src/commit/ad75c260442d93dc0aeb6857407387d4f871b5d6 * NEWS: Add missing parentheses after `grapheme_substr` Co-authored-by: tekimen --- NEWS | 2 +- UPGRADING | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 908838a60dbfb..3f6c29d7a595a 100644 --- a/NEWS +++ b/NEWS @@ -217,7 +217,7 @@ PHP NEWS - Intl: . Added grapheme_strpos(), grapheme_stripos(), grapheme_strrpos(), - grapheme_strripos(), grapheme_strstr(), grapheme_stristr() and + grapheme_strripos(), grapheme_substr(), grapheme_strstr(), grapheme_stristr() and grapheme_levenshtein() functions add $locale parameter (Yuya Hamada). . Fixed bug GH-11952 (Fix locale strings canonicalization for IntlDateFormatter and NumberFormatter). (alexandre-daubois) diff --git a/UPGRADING b/UPGRADING index e58d2875832fd..b60c9b49d7180 100644 --- a/UPGRADING +++ b/UPGRADING @@ -613,8 +613,8 @@ PHP 8.5 UPGRADE NOTES have dropped the false from the return type union. Returning false was actually never possible. . grapheme_strpos(), grapheme_stripos(), grapheme_strrpos(), - grapheme_strripos(), grapheme_strstr(), grapheme_stristr() and - grapheme_levenshtein() functions add $locale parameter. + grapheme_strripos(), grapheme_substr(), grapheme_strstr() + and grapheme_stristr() functions add $locale parameter. RFC: https://wiki.php.net/rfc/grapheme_add_locale_for_case_insensitive - LDAP: From 3273ebef247fef32902284b44ada3082bca8eed5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 20 Oct 2025 12:43:02 +0200 Subject: [PATCH 5/5] .github: Bust the nightly CI cache on Sunday instead of Monday (#20242) The nightly matrix with an empty cache takes several hours to complete due to the amount of jobs. This will effectively block the entire CI for the php organization since there is an organization-wide limit of 20 jobs. Move the cache buster job to Sunday to make it less likely for folks to fight with the Nightly build for resources. --- .github/nightly_matrix.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/nightly_matrix.php b/.github/nightly_matrix.php index 846c60e8fd56d..c1f5627542684 100644 --- a/.github/nightly_matrix.php +++ b/.github/nightly_matrix.php @@ -49,8 +49,8 @@ function get_current_version(): array { $trigger = $argv[1] ?? 'schedule'; $attempt = (int) ($argv[2] ?? 1); -$monday = date('w', time()) === '1'; -$discard_cache = $monday +$sunday = date('w', time()) === '0'; +$discard_cache = $sunday || ($trigger === 'schedule' && $attempt !== 1) || $trigger === 'workflow_dispatch'; if ($discard_cache) {