diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-10-16 20:41:28 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-10-17 06:27:07 -0400 |
| commit | 877393d17ae6a7af55cc360fa10d5cc36367ce8b (patch) | |
| tree | 6ae6ae3c97b341efe05cf89c374cc0f9ed0d6237 | |
| parent | 0b8fca5a195278bb5d5fb1ea09a504c30f751415 (diff) | |
| download | zig-877393d17ae6a7af55cc360fa10d5cc36367ce8b.tar.gz zig-877393d17ae6a7af55cc360fa10d5cc36367ce8b.zip | |
std.fs: fix relative symbolic links on Windows
closes #17564
| -rw-r--r-- | lib/std/fs/test.zig | 17 | ||||
| -rw-r--r-- | lib/std/os/windows.zig | 4 |
2 files changed, 20 insertions, 1 deletions
diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 56477dce7f..6f607bfa45 100644 --- 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 index d40fee8db2..7c0289b689 100644 --- 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, |
