Skip to content

Commit 423761b

Browse files
committed
createWindowsEnvBlock: Reduce NUL terminator count to only what's required
This code previously added 4 NUL code units, but that was likely due to a misinterpretation of this part of the CreateProcess documentation: > A Unicode environment block is terminated by four zero bytes: two for the last string, two more to terminate the block. (four zero *bytes* means *two* zero code units) Additionally, the second zero code unit is only actually needed when the environment is empty due to a quirk of the CreateProcess implementation. In the case of a non-empty environment, there always ends up being two trailing NUL code units since one will come after the last environment variable in the block.
1 parent 2a4e06b commit 423761b

File tree

1 file changed

+10
-7
lines changed

1 file changed

+10
-7
lines changed

lib/std/process.zig

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2036,7 +2036,8 @@ test createNullDelimitedEnvMap {
20362036
pub fn createWindowsEnvBlock(allocator: mem.Allocator, env_map: *const EnvMap) ![]u16 {
20372037
// count bytes needed
20382038
const max_chars_needed = x: {
2039-
var max_chars_needed: usize = 4; // 4 for the final 4 null bytes
2039+
// Only need 2 trailing NUL code units for an empty environment
2040+
var max_chars_needed: usize = if (env_map.count() == 0) 2 else 1;
20402041
var it = env_map.iterator();
20412042
while (it.next()) |pair| {
20422043
// +1 for '='
@@ -2060,12 +2061,14 @@ pub fn createWindowsEnvBlock(allocator: mem.Allocator, env_map: *const EnvMap) !
20602061
}
20612062
result[i] = 0;
20622063
i += 1;
2063-
result[i] = 0;
2064-
i += 1;
2065-
result[i] = 0;
2066-
i += 1;
2067-
result[i] = 0;
2068-
i += 1;
2064+
// An empty environment is a special case that requires a redundant
2065+
// NUL terminator. CreateProcess will read the second code unit even
2066+
// though theoretically the first should be enough to recognize that the
2067+
// environment is empty (see https://nullprogram.com/blog/2023/08/23/)
2068+
if (env_map.count() == 0) {
2069+
result[i] = 0;
2070+
i += 1;
2071+
}
20692072
return try allocator.realloc(result, i);
20702073
}
20712074

0 commit comments

Comments
 (0)