commit 877393d17ae6a7af55cc360fa10d5cc36367ce8b (tree)
parent 0b8fca5a195278bb5d5fb1ea09a504c30f751415
Author: Andrew Kelley <andrew@ziglang.org>
Date: Mon, 16 Oct 2023 20:41:28 -0700
std.fs: fix relative symbolic links on Windows
closes #17564
Diffstat:
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/lib/std/fs/test.zig b/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 {
diff --git a/lib/std/os/windows.zig b/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,