[php-src] PHP-8.5: Merge branch 'PHP-8.4' into PHP-8.5
Ilia Alshanetsky <[email protected]>
| Newsgroups | gmane.comp.php.cvs.general |
|---|---|
| Message-ID | <[email protected]> |
Author: Ilia Alshanetsky (iliaal)
Date: 2026-07-16T22:12:57-04:00
Commit: https://github.com/php/php-src/commit/1ca5d65428b1fcd9252a4732da71fa49418cf020
Raw diff: https://github.com/php/php-src/commit/1ca5d65428b1fcd9252a4732da71fa49418cf020.diff
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
ext/standard: fix out-of-bounds access in the ftp:// directory stream
Changed paths:
A ext/standard/tests/streams/ftp_dirstream_oob.phpt
M ext/ftp/tests/server.inc
M ext/standard/ftp_fopen_wrapper.c
M ext/standard/tests/streams/opendir-002.phpt
M ext/standard/tests/streams/opendir-004.phpt
Diff:
diff --git a/ext/ftp/tests/server.inc b/ext/ftp/tests/server.inc
index 04e2ceefa278..65c1af1b7aab 100644
--- a/ext/ftp/tests/server.inc
+++ b/ext/ftp/tests/server.inc
@@ -290,7 +290,7 @@ if ($pid) {
}
if (empty($m[1]) || $m[1] !== 'emptydir') {
- fputs($fs, "file1\r\nfile1\r\nfile\nb0rk\r\n");
+ fputs($fs, $nlst_data ?? "file1\r\nfile1\r\nfile\nb0rk\r\n");
}
fputs($s, "226 Closing data Connection.\r\n");
diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c
index 3330c5493dbf..c1f8fe7424b9 100644
--- a/ext/standard/ftp_fopen_wrapper.c
+++ b/ext/standard/ftp_fopen_wrapper.c
@@ -633,9 +633,9 @@ static ssize_t php_ftp_dirstream_read(php_stream *stream, char *buf, size_t coun
basename = php_basename(ent->d_name, tmp_len, NULL, 0);
- tmp_len = MIN(sizeof(ent->d_name), ZSTR_LEN(basename) - 1);
+ tmp_len = MIN(sizeof(ent->d_name) - 1, ZSTR_LEN(basename));
memcpy(ent->d_name, ZSTR_VAL(basename), tmp_len);
- ent->d_name[tmp_len - 1] = '\0';
+ ent->d_name[tmp_len] = '\0';
zend_string_release_ex(basename, 0);
ent->d_type = DT_UNKNOWN;
diff --git a/ext/standard/tests/streams/ftp_dirstream_oob.phpt b/ext/standard/tests/streams/ftp_dirstream_oob.phpt
new file mode 100644
index 000000000000..9e184f3c8ac6
--- /dev/null
+++ b/ext/standard/tests/streams/ftp_dirstream_oob.phpt
@@ -0,0 +1,33 @@
+--TEST--
+opendir() with 'ftp://' stream must not go out of bounds on an empty or slash-only listing line
+--SKIPIF--
+<?php
+if (array_search('ftp',stream_get_wrappers()) === FALSE) die("skip ftp wrapper not available.");
+if (!function_exists('pcntl_fork')) die("skip pcntl_fork() not available.");
+?>
+--FILE--
+<?php
+
+/* An empty line makes php_basename() return "\n" and a slash-only final line
+ * makes it return "", the two lengths the buffer math underflowed on. */
+$nlst_data = "file1\r\n\nb0rk\r\n/";
+
+require __DIR__ . "/../../../ftp/tests/server.inc";
+
+$path="ftp://localhost:" . $port."/";
+
+$ds=opendir($path);
+var_dump($ds);
+
+while (($fn=readdir($ds)) !== false) {
+ var_dump($fn);
+}
+
+closedir($ds);
+?>
+--EXPECTF--
+resource(%d) of type (stream)
+string(5) "file1"
+string(0) ""
+string(4) "b0rk"
+string(0) ""
diff --git a/ext/standard/tests/streams/opendir-002.phpt b/ext/standard/tests/streams/opendir-002.phpt
index 4978c8affa3d..0a5712564e2e 100644
--- a/ext/standard/tests/streams/opendir-002.phpt
+++ b/ext/standard/tests/streams/opendir-002.phpt
@@ -25,5 +25,5 @@ closedir($ds);
resource(%d) of type (stream)
string(5) "file1"
string(5) "file1"
-string(3) "fil"
+string(4) "file"
string(4) "b0rk"
diff --git a/ext/standard/tests/streams/opendir-004.phpt b/ext/standard/tests/streams/opendir-004.phpt
index 9ccb86b4f4b4..3f076e0d8386 100644
--- a/ext/standard/tests/streams/opendir-004.phpt
+++ b/ext/standard/tests/streams/opendir-004.phpt
@@ -27,5 +27,5 @@ while ($fn=readdir($ds)) {
resource(%d) of type (stream)
string(5) "file1"
string(5) "file1"
-string(3) "fil"
+string(4) "file"
string(4) "b0rk"