From ae59c694674aa7e65950d264d2ccaf0d1bedcf5c Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 14 Dec 2025 14:44:04 +0000 Subject: [PATCH 1/5] ext/spl: DirectoryIterator to support modern filesytems. With filesystems with builtin large capacity such as ZFS, Btfrs, NTFS or even ext4 with large_dir feature enabled, an int to represent an entry index is falling short, thus risking overflows. A zend_long however should cover this need without increasing out internal data structure. close GH-20705 --- NEWS | 4 ++++ ext/spl/spl_directory.c | 2 +- ext/spl/spl_directory.h | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 671d2b57a676..534daec19b37 100644 --- a/NEWS +++ b/NEWS @@ -50,6 +50,10 @@ PHP NEWS . Soap::__setCookie() when cookie name is a digit is now not stored and represented as a string anymore but a int. (David Carlier) +- SPL: + . DirectoryIterator key can now work better with filesystem supporting larger + directory indexing. (David Carlier) + - Standard: . Fixed bug GH-19926 (reset internal pointer earlier while splicing array while COW violation flag is still set). (alexandre-daubois) diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 6a5fc1757f26..86e4b11334c8 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -414,7 +414,7 @@ static zend_object *spl_filesystem_object_clone(zend_object *old_object) spl_filesystem_dir_open(intern, source->path); /* read until we hit the position in which we were before */ bool skip_dots = SPL_HAS_FLAG(source->flags, SPL_FILE_DIR_SKIPDOTS); - int index; + zend_long index; for (index = 0; index < source->u.dir.index; ++index) { do { spl_filesystem_dir_read(intern); diff --git a/ext/spl/spl_directory.h b/ext/spl/spl_directory.h index 549dfb1dc4d0..a2d1d8d85475 100644 --- a/ext/spl/spl_directory.h +++ b/ext/spl/spl_directory.h @@ -62,7 +62,7 @@ struct _spl_filesystem_object { struct { php_stream *dirp; zend_string *sub_path; - int index; + zend_long index; zend_function *func_rewind; zend_function *func_next; zend_function *func_valid; From acd0898bdfb12fb34f422b3fffe54d747f89c235 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+ndossche@users.noreply.github.com> Date: Sat, 13 Dec 2025 14:26:27 +0100 Subject: [PATCH 2/5] Fix GH-20699: SQLite3Result fetchArray return array|false, null returned Closes GH-20701. --- NEWS | 4 ++++ ext/sqlite3/sqlite3.c | 1 + ext/sqlite3/tests/gh20699.phpt | 14 ++++++++++++++ 3 files changed, 19 insertions(+) create mode 100644 ext/sqlite3/tests/gh20699.phpt diff --git a/NEWS b/NEWS index 13f673a53c02..4e301bdbc8b0 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,10 @@ PHP NEWS . Fixed bug GH-20678 (resource created by GlobIterator crashes with fclose()). (David Carlier) +- Sqlite3: + . Fixed bug GH-20699 (SQLite3Result fetchArray return array|false, + null returned). (ndossche, plusminmax) + - Standard: . Fix error check for proc_open() command. (ndossche) diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 9b3286b70220..b16be6932a07 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -2011,6 +2011,7 @@ PHP_METHOD(SQLite3Result, fetchArray) default: php_sqlite3_error(result_obj->db_obj, sqlite3_errcode(sqlite3_db_handle(result_obj->stmt_obj->stmt)), "Unable to execute statement: %s", sqlite3_errmsg(sqlite3_db_handle(result_obj->stmt_obj->stmt))); + RETURN_FALSE; } } /* }}} */ diff --git a/ext/sqlite3/tests/gh20699.phpt b/ext/sqlite3/tests/gh20699.phpt new file mode 100644 index 000000000000..1b53bfc98e39 --- /dev/null +++ b/ext/sqlite3/tests/gh20699.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-20699 (SQLite3Result fetchArray return array|false, null returned) +--EXTENSIONS-- +sqlite3 +--CREDITS-- +plusminmax +--FILE-- +prepare('BEGIN;')->execute()->fetchArray()); +?> +--EXPECTF-- +Warning: SQLite3Result::fetchArray(): Unable to execute statement: cannot start a transaction within a transaction in %s on line %d +bool(false) From 5850c7de7c5032a84edbde17360de3ddc00fce57 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 21 Feb 2023 16:50:31 +0100 Subject: [PATCH 3/5] sapi/fpm: remove use of variable-length arrays (#10645) According to @cmb69, PHP does not require VLA support (https://github.com/php/php-src/pull/10304#discussion_r1069343092). VLAs are a bad idea for several reasons, so let's get rid of them. Two of the VLAs were probably unintended; unlike C++, C doesn't have the concept of "constant expressions", so an array with a "const" length is technically still a VLA. This is fixed by removing the "const" variable, and using sizeof() instead. (cherry picked from commit ff2a211d55650201e5bbe370c319a0c913613eb9) --- sapi/fpm/fpm/fpm_php_trace.c | 11 +++++------ sapi/fpm/fpm/fpm_stdio.c | 5 ++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/sapi/fpm/fpm/fpm_php_trace.c b/sapi/fpm/fpm/fpm_php_trace.c index 0e1d8e3f6cee..b1535b26e3ef 100644 --- a/sapi/fpm/fpm/fpm_php_trace.c +++ b/sapi/fpm/fpm/fpm_php_trace.c @@ -39,15 +39,14 @@ static int fpm_php_trace_dump(struct fpm_child_s *child, FILE *slowlog) /* {{{ * int callers_limit = child->wp->config->request_slowlog_trace_depth; pid_t pid = child->pid; struct timeval tv; - static const int buf_size = 1024; - char buf[buf_size]; + char buf[1024]; long execute_data; long path_translated; long l; gettimeofday(&tv, 0); - zlog_print_time(&tv, buf, buf_size); + zlog_print_time(&tv, buf, sizeof(buf)); fprintf(slowlog, "\n%s [pool %s] pid %d\n", buf, child->wp->config->name, (int) pid); @@ -57,7 +56,7 @@ static int fpm_php_trace_dump(struct fpm_child_s *child, FILE *slowlog) /* {{{ * path_translated = l; - if (0 > fpm_trace_get_strz(buf, buf_size, path_translated)) { + if (0 > fpm_trace_get_strz(buf, sizeof(buf), path_translated)) { return -1; } @@ -103,7 +102,7 @@ static int fpm_php_trace_dump(struct fpm_child_s *child, FILE *slowlog) /* {{{ * ZEND_UNREACHABLE(); } } else { - if (0 > fpm_trace_get_strz(buf, buf_size, function_name + offsetof(zend_string, val))) { + if (0 > fpm_trace_get_strz(buf, sizeof(buf), function_name + offsetof(zend_string, val))) { return -1; } @@ -149,7 +148,7 @@ static int fpm_php_trace_dump(struct fpm_child_s *child, FILE *slowlog) /* {{{ * file_name = l; - if (0 > fpm_trace_get_strz(buf, buf_size, file_name + offsetof(zend_string, val))) { + if (0 > fpm_trace_get_strz(buf, sizeof(buf), file_name + offsetof(zend_string, val))) { return -1; } diff --git a/sapi/fpm/fpm/fpm_stdio.c b/sapi/fpm/fpm/fpm_stdio.c index dec540d17aca..c104ff987f0c 100644 --- a/sapi/fpm/fpm/fpm_stdio.c +++ b/sapi/fpm/fpm/fpm_stdio.c @@ -168,9 +168,8 @@ int fpm_stdio_flush_child(void) static void fpm_stdio_child_said(struct fpm_event_s *ev, short which, void *arg) /* {{{ */ { - static const int max_buf_size = 1024; int fd = ev->fd; - char buf[max_buf_size]; + char buf[1024]; struct fpm_child_s *child; int is_stdout; struct fpm_event_s *event; @@ -216,7 +215,7 @@ static void fpm_stdio_child_said(struct fpm_event_s *ev, short which, void *arg) while (1) { stdio_read: - in_buf = read(fd, buf, max_buf_size - 1); + in_buf = read(fd, buf, sizeof(buf) - 1); if (in_buf <= 0) { /* no data */ if (in_buf == 0 || !PHP_IS_TRANSIENT_ERROR(errno)) { /* pipe is closed or error */ From 85913fc61b57b28b74a9803f3055bdced5c31656 Mon Sep 17 00:00:00 2001 From: Yuya Hamada Date: Wed, 10 Dec 2025 21:16:44 +0900 Subject: [PATCH 4/5] Fix GH-20674 mb_decode_mimeheader does not handle separator `?= =?` is skipped if long term, so skip space character. Add test case from RFC2047 and fix last pattern See: https://www.ietf.org/rfc/rfc2047#section-8 --- NEWS | 2 ++ ext/mbstring/mbstring.c | 4 +++- ext/mbstring/tests/gh20674.phpt | 40 +++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 ext/mbstring/tests/gh20674.phpt diff --git a/NEWS b/NEWS index 534daec19b37..181c00bd8385 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,8 @@ PHP NEWS . ini_set() with mbstring.detect_order changes the order of mb_detect_order as intended, since mbstring.detect_order is an INI_ALL setting. (tobee94) . Added GB18030-2022 to default encoding list for zh-CN. (HeRaNO) + . Fixed bug GH-20674 (Fix GH-20674 mb_decode_mimeheader does not handle + separator). (Yuya Hamada) - Opcache: . Fixed bug GH-20051 (apache2 shutdowns when restart is requested during diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 7422c600284d..118986411a8b 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -6675,13 +6675,15 @@ static zend_string* mb_mime_header_decode(zend_string *input, const mbfl_encodin p = temp; /* Decoding of MIME encoded word was successful; * Try to collapse a run of whitespace */ - if (p < e && (*p == '\n' || *p == '\r')) { + if (p < e && (*p == '\n' || *p == '\r' || *p == '\t' || *p == ' ')) { do { p++; } while (p < e && (*p == '\n' || *p == '\r' || *p == '\t' || *p == ' ')); /* We will only actually output a space if this is not immediately followed * by another valid encoded word */ space_pending = true; + } else { + space_pending = false; } continue; } diff --git a/ext/mbstring/tests/gh20674.phpt b/ext/mbstring/tests/gh20674.phpt new file mode 100644 index 000000000000..2fb8206037de --- /dev/null +++ b/ext/mbstring/tests/gh20674.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-20674 (mb_decode_mimeheader does not handle separator) +--EXTENSIONS-- +mbstring +--FILE-- + +--EXPECTF-- +string(11) "The PHP 8.5" +string(11) "The PHP 8.5" +string(11) "The PHP 8.5" +string(11) "The PHP 8.5" +string(3) "(a)" +string(5) "(a b)" +string(5) "(a b)" +string(4) "(ab)" +string(4) "(ab)" +string(4) "(ab)" From 0056d013bf505302e2477e02d795627709842327 Mon Sep 17 00:00:00 2001 From: Yuya Hamada Date: Wed, 10 Dec 2025 21:16:44 +0900 Subject: [PATCH 5/5] Fix GH-20674 mb_decode_mimeheader does not handle separator `?= =?` is skipped if long term, so skip space character. Add test case from RFC2047 and fix last pattern See: https://www.ietf.org/rfc/rfc2047#section-8 --- NEWS | 4 ++++ ext/mbstring/mbstring.c | 4 +++- ext/mbstring/tests/gh20674.phpt | 40 +++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 ext/mbstring/tests/gh20674.phpt diff --git a/NEWS b/NEWS index 4e301bdbc8b0..5103b4a96791 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,10 @@ PHP NEWS - LDAP: . Fix memory leak in ldap_set_options(). (ndossche) +- Mbstring + . Fixed bug GH-20674 (Fix GH-20674 mb_decode_mimeheader does not handle + separator). (Yuya Hamada) + - SPL: . Fixed bug GH-20678 (resource created by GlobIterator crashes with fclose()). (David Carlier) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 1d5c27a2a381..5839945d4757 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -6395,13 +6395,15 @@ static zend_string* mb_mime_header_decode(zend_string *input, const mbfl_encodin p = temp; /* Decoding of MIME encoded word was successful; * Try to collapse a run of whitespace */ - if (p < e && (*p == '\n' || *p == '\r')) { + if (p < e && (*p == '\n' || *p == '\r' || *p == '\t' || *p == ' ')) { do { p++; } while (p < e && (*p == '\n' || *p == '\r' || *p == '\t' || *p == ' ')); /* We will only actually output a space if this is not immediately followed * by another valid encoded word */ space_pending = true; + } else { + space_pending = false; } continue; } diff --git a/ext/mbstring/tests/gh20674.phpt b/ext/mbstring/tests/gh20674.phpt new file mode 100644 index 000000000000..2fb8206037de --- /dev/null +++ b/ext/mbstring/tests/gh20674.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-20674 (mb_decode_mimeheader does not handle separator) +--EXTENSIONS-- +mbstring +--FILE-- + +--EXPECTF-- +string(11) "The PHP 8.5" +string(11) "The PHP 8.5" +string(11) "The PHP 8.5" +string(11) "The PHP 8.5" +string(3) "(a)" +string(5) "(a b)" +string(5) "(a b)" +string(4) "(ab)" +string(4) "(ab)" +string(4) "(ab)"