Commit 877393d17a

Andrew Kelley <andrew@ziglang.org>
2023-10-17 05:41:28
std.fs: fix relative symbolic links on Windows
closes #17564
1 parent 0b8fca5
Changed files (2)
lib
lib/std/fs/test.zig
@@ -160,6 +160,23 @@ fn testReadLink(dir: Dir, target_path: []const u8, symlink_path: []const u8) !vo
     try testing.expectEqualStrings(target_path, given);
 }
 
+test "relative symlink to parent directory" {
+    var tmp = tmpDir(.{});
+    defer tmp.cleanup();
+
+    var subdir = try tmp.dir.makeOpenPath("subdir", .{});
+    defer subdir.close();
+
+    const expected_link_name = ".." ++ std.fs.path.sep_str ++ "b.txt";
+
+    try subdir.symLink(expected_link_name, "a.txt", .{});
+
+    var buf: [1000]u8 = undefined;
+    const link_name = try subdir.readLink("a.txt", &buf);
+
+    try testing.expectEqualStrings(expected_link_name, link_name);
+}
+
 test "openDir" {
     try testWithAllSupportedPathTypes(struct {
         fn impl(ctx: *TestContext) !void {
lib/std/os/windows.zig
@@ -766,7 +766,9 @@ pub fn CreateSymbolicLink(
                 //       it will still resolve the path relative to the root of
                 //       the C:\ drive.
                 .rooted => break :target_path target_path,
-                else => {},
+                // Keep relative paths relative, but anything else needs to get NT-prefixed.
+                else => if (!std.fs.path.isAbsoluteWindowsWTF16(target_path))
+                    break :target_path target_path,
             },
             // Already an NT path, no need to do anything to it
             .nt => break :target_path target_path,