Commit 3db8cffa3b

Ryan Liptak <squeek502@hotmail.com>
2022-12-18 15:30:21
spawnWindows: Fix PATH searching when cwd is absolute
Fixes a regression caused by https://github.com/ziglang/zig/pull/13983 From the added comment: We still search the path if the cwd is absolute because of the "cwd set in ChildProcess is in effect when choosing the executable path to match posix semantics" behavior--we don't want to skip searching the PATH just because we were trying to set the cwd of the child process.
1 parent 3bfae2a
Changed files (2)
lib
test
standalone
windows_spawn
lib/std/child_process.zig
@@ -1022,8 +1022,12 @@ pub const ChildProcess = struct {
                 };
 
                 // If the app name had path separators, that disallows PATH searching,
-                // and there's no need to search the PATH if the cwd path is absolute.
-                if (app_dirname_w != null or fs.path.isAbsoluteWindowsWTF16(cwd_path_w)) {
+                // and there's no need to search the PATH if the app name is absolute.
+                // We still search the path if the cwd is absolute because of the
+                // "cwd set in ChildProcess is in effect when choosing the executable path
+                // to match posix semantics" behavior--we don't want to skip searching
+                // the PATH just because we were trying to set the cwd of the child process.
+                if (app_dirname_w != null or app_name_is_absolute) {
                     return original_err;
                 }
 
test/standalone/windows_spawn/main.zig
@@ -142,6 +142,10 @@ pub fn main() anyerror!void {
     defer allocator.free(goodbye_abs_path);
     // then the PATH should not be searched and we should get InvalidExe
     try testExecError(error.InvalidExe, allocator, goodbye_abs_path);
+
+    // If we try to exec but provide a cwd that is an absolute path, the PATH
+    // should still be searched and the goodbye.exe in something should be found.
+    try testExecWithCwd(allocator, "goodbye", tmp_absolute_path, "hello from exe\n");
 }
 
 fn testExecError(err: anyerror, allocator: std.mem.Allocator, command: []const u8) !void {
@@ -149,9 +153,14 @@ fn testExecError(err: anyerror, allocator: std.mem.Allocator, command: []const u
 }
 
 fn testExec(allocator: std.mem.Allocator, command: []const u8, expected_stdout: []const u8) !void {
+    return testExecWithCwd(allocator, command, null, expected_stdout);
+}
+
+fn testExecWithCwd(allocator: std.mem.Allocator, command: []const u8, cwd: ?[]const u8, expected_stdout: []const u8) !void {
     var result = try std.ChildProcess.exec(.{
         .allocator = allocator,
         .argv = &[_][]const u8{command},
+        .cwd = cwd,
     });
     defer allocator.free(result.stdout);
     defer allocator.free(result.stderr);