Commit 28f668d88fe for php.net

commit 28f668d88fec2bcfac590ddc273dcd6c8c3fda54
Author: Weilin Du <108666168+LamentXU123@users.noreply.github.com>
Date:   Sun May 3 02:08:10 2026 +0800

    ext/standard: Reject null bytes in proc_open() $cwd (#21871)

diff --git a/NEWS b/NEWS
index 5453a5fc094..fd17715973a 100644
--- a/NEWS
+++ b/NEWS
@@ -186,6 +186,8 @@ PHP                                                                        NEWS
     (Weilin Du)
   . getenv() and putenv() now raises a ValueError when the first argument
     contains null bytes. (Weilin Du)
+  . proc_open() now raises a ValueError when the $cwd argument contains
+    null bytes. (Weilin Du)

 - Streams:
   . Added so_keepalive, tcp_keepidle, tcp_keepintvl and tcp_keepcnt stream
diff --git a/UPGRADING b/UPGRADING
index e55e03be48b..088f5b620bd 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -102,6 +102,8 @@ PHP 8.6 UPGRADE NOTES
     argument value is passed.
   . scandir() now raises a ValueError when an invalid $sorting_order
     argument value is passed.
+  . proc_open() now raises a ValueError when the $cwd argument contains
+    null bytes.

 - Zip:
   . ZipArchive::extractTo now raises a TypeError for the
diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c
index edccbeae564..11111140679 100644
--- a/ext/standard/proc_open.c
+++ b/ext/standard/proc_open.c
@@ -1240,7 +1240,7 @@ PHP_FUNCTION(proc_open)
 		Z_PARAM_ARRAY_HT(descriptorspec)
 		Z_PARAM_ZVAL(pipes)
 		Z_PARAM_OPTIONAL
-		Z_PARAM_STRING_OR_NULL(cwd, cwd_len)
+		Z_PARAM_PATH_OR_NULL(cwd, cwd_len)
 		Z_PARAM_ARRAY_HT_OR_NULL(environment)
 		Z_PARAM_ARRAY_OR_NULL(other_options)
 	ZEND_PARSE_PARAMETERS_END();
diff --git a/ext/standard/tests/general_functions/proc_open_cwd_null_bytes.phpt b/ext/standard/tests/general_functions/proc_open_cwd_null_bytes.phpt
new file mode 100644
index 00000000000..faa86c82417
--- /dev/null
+++ b/ext/standard/tests/general_functions/proc_open_cwd_null_bytes.phpt
@@ -0,0 +1,18 @@
+--TEST--
+proc_open() rejects null bytes in cwd
+--SKIPIF--
+<?php
+if (!function_exists("proc_open")) echo "skip proc_open() is not available";
+?>
+--FILE--
+<?php
+
+try {
+    proc_open("does_not_matter", [], $pipes, "foo\0bar");
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+
+?>
+--EXPECT--
+proc_open(): Argument #4 ($cwd) must not contain any null bytes