Commit 701d8a66d32 for php.net

commit 701d8a66d327beae2b83d6c7d53711717bec14fb
Author: Weilin Du <108666168+LamentXU123@users.noreply.github.com>
Date:   Tue Apr 21 20:37:59 2026 +0800

    ext/standard: Throw a ValueError when the parameter includes NUL bytes in `putenv` and `getenv` (#21817)

diff --git a/NEWS b/NEWS
index 73a2b3d6637..22762f98c2c 100644
--- a/NEWS
+++ b/NEWS
@@ -170,6 +170,8 @@ PHP                                                                        NEWS
     argument value is passed. (Girgias)
   . linkinfo() now raises a ValueError when the argument is an empty string.
     (Weilin Du)
+  . getenv() and putenv() now raises a ValueError when the first 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 9c3d5a2b29a..869e265af8a 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -88,6 +88,8 @@ PHP 8.6 UPGRADE NOTES
     argument value is passed.
   . array_change_key_case() now raises a ValueError when an invalid $case
     argument value is passed.
+  . getenv() and putenv() now raises a ValueError when the first argument
+    contains null bytes.
   . linkinfo() now raises a ValueError when the $path argument is empty.
   . pathinfo() now raises a ValueError when an invalid $flag
     argument value is passed.
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index ece7f1278f7..5c6b1ce1d1d 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -696,7 +696,7 @@ PHP_FUNCTION(getenv)

 	ZEND_PARSE_PARAMETERS_START(0, 2)
 		Z_PARAM_OPTIONAL
-		Z_PARAM_STRING_OR_NULL(str, str_len)
+		Z_PARAM_PATH_OR_NULL(str, str_len)
 		Z_PARAM_BOOL(local_only)
 	ZEND_PARSE_PARAMETERS_END();

@@ -739,7 +739,7 @@ PHP_FUNCTION(putenv)
 #endif

 	ZEND_PARSE_PARAMETERS_START(1, 1)
-		Z_PARAM_STRING(setting, setting_len)
+		Z_PARAM_PATH(setting, setting_len)
 	ZEND_PARSE_PARAMETERS_END();

 	if (setting_len == 0 || setting[0] == '=') {
diff --git a/ext/standard/tests/general_functions/putenv_and_getenv_reject_null_bytes.phpt b/ext/standard/tests/general_functions/putenv_and_getenv_reject_null_bytes.phpt
new file mode 100644
index 00000000000..28a34623733
--- /dev/null
+++ b/ext/standard/tests/general_functions/putenv_and_getenv_reject_null_bytes.phpt
@@ -0,0 +1,35 @@
+--TEST--
+getenv() and putenv() reject null bytes
+--FILE--
+<?php
+
+foreach ([false, true] as $local_only) {
+    try {
+        getenv("PHP_GETENV_NUL_TEST\0SUFFIX", $local_only);
+    } catch (ValueError $exception) {
+        echo $exception->getMessage() . "\n";
+    }
+}
+
+$var_name = 'PHP_PUTENV_NUL_TEST';
+
+foreach ([
+    $var_name . "\0SUFFIX=value",
+    $var_name . "=va\0lue",
+] as $assignment) {
+    try {
+        putenv($assignment);
+    } catch (ValueError $exception) {
+        echo $exception->getMessage() . "\n";
+    }
+}
+
+var_dump(getenv($var_name));
+
+?>
+--EXPECT--
+getenv(): Argument #1 ($name) must not contain any null bytes
+getenv(): Argument #1 ($name) must not contain any null bytes
+putenv(): Argument #1 ($assignment) must not contain any null bytes
+putenv(): Argument #1 ($assignment) must not contain any null bytes
+bool(false)