| author | |
| committer | |
| log | e233971e4fe19953ce8af63860a0791f5ca1268e |
| tree | f101253289a65aa2fa19ebe305e915daa2775171 |
| parent | 147beec7da5f3eb3a858037b806ad8b1b66bfffc |
Symlink targets require canonicalized path separators on Windows2 files changed, 23 insertions(+), 0 deletions(-)
lib/std/fs/Dir.zig+10| ... | ... | @@ -1705,6 +1705,15 @@ pub fn symLink( |
| 1705 | 1705 | var target_path_w: std.os.windows.PathSpace = undefined; |
| 1706 | 1706 | target_path_w.len = try std.unicode.wtf8ToWtf16Le(&target_path_w.data, target_path); |
| 1707 | 1707 | target_path_w.data[target_path_w.len] = 0; |
| 1708 | // However, we need to canonicalize any path separators to `\`, since if | |
| 1709 | // the target path is relative, then it must use `\` as the path separator. | |
| 1710 | mem.replaceScalar( | |
| 1711 | u16, | |
| 1712 | target_path_w.data[0..target_path_w.len], | |
| 1713 | mem.nativeToLittle(u16, '/'), | |
| 1714 | mem.nativeToLittle(u16, '\\'), | |
| 1715 | ); | |
| 1716 | ||
| 1708 | 1717 | const sym_link_path_w = try std.os.windows.sliceToPrefixedFileW(self.fd, sym_link_path); |
| 1709 | 1718 | return self.symLinkW(target_path_w.span(), sym_link_path_w.span(), flags); |
| 1710 | 1719 | } |
| ... | ... | @@ -1744,6 +1753,7 @@ pub fn symLinkW( |
| 1744 | 1753 | self: Dir, |
| 1745 | 1754 | /// WTF-16, does not need to be NT-prefixed. The NT-prefixing |
| 1746 | 1755 | /// of this path is handled by CreateSymbolicLink. |
| 1756 | /// Any path separators must be `\`, not `/`. | |
| 1747 | 1757 | target_path_w: [:0]const u16, |
| 1748 | 1758 | /// WTF-16, must be NT-prefixed or relative |
| 1749 | 1759 | sym_link_path_w: []const u16, |
lib/std/fs/test.zig+13| ... | ... | @@ -178,6 +178,19 @@ fn testReadLinkAbsolute(target_path: []const u8, symlink_path: []const u8) !void |
| 178 | 178 | try testing.expectEqualStrings(target_path, given); |
| 179 | 179 | } |
| 180 | 180 | |
| 181 | test "Dir.symLink with relative target that has a / path separator" { | |
| 182 | var tmp = testing.tmpDir(.{}); | |
| 183 | defer tmp.cleanup(); | |
| 184 | ||
| 185 | try tmp.dir.makePath("a"); | |
| 186 | try tmp.dir.writeFile("a/file", ""); | |
| 187 | try tmp.dir.symLink("a/file", "symlink", .{}); | |
| 188 | ||
| 189 | const stat = try tmp.dir.statFile("symlink"); | |
| 190 | // statFile follows symlinks | |
| 191 | try testing.expectEqual(File.Kind.file, stat.kind); | |
| 192 | } | |
| 193 | ||
| 181 | 194 | test "File.stat on a File that is a symlink returns Kind.sym_link" { |
| 182 | 195 | // This test requires getting a file descriptor of a symlink which |
| 183 | 196 | // is not possible on all targets |