| author | |
| committer | |
| log | ecdf75d04e0b0193934d019e08aa46c45b67bef4 |
| tree | 7d28d08307587391572fda48d520c93aed3a9ca2 |
| parent | 45f4a1124f80219d9237d6809ecb919a8896723a |
| parent | 1e04e852009b969741e2969f2aeedb72d73d326a |
| signature |
zig fmt: Fix relative paths with . and .. on Windows as well as forward slashes3 files changed, 31 insertions(+), 15 deletions(-)
lib/std/io/buffered_atomic_file.zig+7-3| ... | ... | @@ -15,8 +15,12 @@ pub const BufferedAtomicFile = struct { |
| 15 | 15 | |
| 16 | 16 | /// TODO when https://github.com/ziglang/zig/issues/2761 is solved |
| 17 | 17 | /// this API will not need an allocator |
| 18 | /// TODO integrate this with Dir API | |
| 19 | pub fn create(allocator: *mem.Allocator, dest_path: []const u8) !*BufferedAtomicFile { | |
| 18 | pub fn create( | |
| 19 | allocator: *mem.Allocator, | |
| 20 | dir: fs.Dir, | |
| 21 | dest_path: []const u8, | |
| 22 | atomic_file_options: fs.Dir.AtomicFileOptions, | |
| 23 | ) !*BufferedAtomicFile { | |
| 20 | 24 | var self = try allocator.create(BufferedAtomicFile); |
| 21 | 25 | self.* = BufferedAtomicFile{ |
| 22 | 26 | .atomic_file = undefined, |
| ... | ... | @@ -26,7 +30,7 @@ pub const BufferedAtomicFile = struct { |
| 26 | 30 | }; |
| 27 | 31 | errdefer allocator.destroy(self); |
| 28 | 32 | |
| 29 | self.atomic_file = try fs.cwd().atomicFile(dest_path, .{}); | |
| 33 | self.atomic_file = try dir.atomicFile(dest_path, atomic_file_options); | |
| 30 | 34 | errdefer self.atomic_file.deinit(); |
| 31 | 35 | |
| 32 | 36 | self.file_stream = self.atomic_file.file.outStream(); |
lib/std/os/windows.zig+12-7| ... | ... | @@ -1260,15 +1260,9 @@ pub fn wToPrefixedFileW(s: []const u16) ![PATH_MAX_WIDE:0]u16 { |
| 1260 | 1260 | pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16) ![PATH_MAX_WIDE + suffix.len:0]u16 { |
| 1261 | 1261 | // TODO https://github.com/ziglang/zig/issues/2765 |
| 1262 | 1262 | var result: [PATH_MAX_WIDE + suffix.len:0]u16 = undefined; |
| 1263 | // > File I/O functions in the Windows API convert "/" to "\" as part of | |
| 1264 | // > converting the name to an NT-style name, except when using the "\\?\" | |
| 1265 | // > prefix as detailed in the following sections. | |
| 1266 | // from https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation | |
| 1267 | // Because we want the larger maximum path length for absolute paths, we | |
| 1268 | // disallow forward slashes in zig std lib file functions on Windows. | |
| 1269 | 1263 | for (s) |byte| { |
| 1270 | 1264 | switch (byte) { |
| 1271 | '/', '*', '?', '"', '<', '>', '|' => return error.BadPathName, | |
| 1265 | '*', '?', '"', '<', '>', '|' => return error.BadPathName, | |
| 1272 | 1266 | else => {}, |
| 1273 | 1267 | } |
| 1274 | 1268 | } |
| ... | ... | @@ -1279,6 +1273,17 @@ pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16) |
| 1279 | 1273 | }; |
| 1280 | 1274 | const end_index = start_index + try std.unicode.utf8ToUtf16Le(result[start_index..], s); |
| 1281 | 1275 | if (end_index + suffix.len > result.len) return error.NameTooLong; |
| 1276 | // > File I/O functions in the Windows API convert "/" to "\" as part of | |
| 1277 | // > converting the name to an NT-style name, except when using the "\\?\" | |
| 1278 | // > prefix as detailed in the following sections. | |
| 1279 | // from https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation | |
| 1280 | // Because we want the larger maximum path length for absolute paths, we | |
| 1281 | // convert forward slashes to backward slashes here. | |
| 1282 | for (result[0..end_index]) |*elem| { | |
| 1283 | if (elem.* == '/') { | |
| 1284 | elem.* = '\\'; | |
| 1285 | } | |
| 1286 | } | |
| 1282 | 1287 | mem.copy(u16, result[end_index..], suffix); |
| 1283 | 1288 | result[end_index + suffix.len] = 0; |
| 1284 | 1289 | return result; |
src-self-hosted/stage2.zig+12-5| ... | ... | @@ -318,11 +318,18 @@ const FmtError = error{ |
| 318 | 318 | } || fs.File.OpenError; |
| 319 | 319 | |
| 320 | 320 | fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { |
| 321 | if (fmt.seen.exists(file_path)) return; | |
| 322 | try fmt.seen.put(file_path); | |
| 321 | // get the real path here to avoid Windows failing on relative file paths with . or .. in them | |
| 322 | var real_path = fs.realpathAlloc(fmt.allocator, file_path) catch |err| { | |
| 323 | try stderr.print("unable to open '{}': {}\n", .{ file_path, err }); | |
| 324 | fmt.any_error = true; | |
| 325 | return; | |
| 326 | }; | |
| 327 | defer fmt.allocator.free(real_path); | |
| 328 | ||
| 329 | if (fmt.seen.exists(real_path)) return; | |
| 330 | try fmt.seen.put(real_path); | |
| 323 | 331 | |
| 324 | const max = std.math.maxInt(usize); | |
| 325 | const source_code = fs.cwd().readFileAlloc(fmt.allocator, file_path, max) catch |err| switch (err) { | |
| 332 | const source_code = fs.cwd().readFileAlloc(fmt.allocator, real_path, self_hosted_main.max_src_size) catch |err| switch (err) { | |
| 326 | 333 | error.IsDir, error.AccessDenied => { |
| 327 | 334 | // TODO make event based (and dir.next()) |
| 328 | 335 | var dir = try fs.cwd().openDir(file_path, .{ .iterate = true }); |
| ... | ... | @@ -370,7 +377,7 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { |
| 370 | 377 | fmt.any_error = true; |
| 371 | 378 | } |
| 372 | 379 | } else { |
| 373 | const baf = try io.BufferedAtomicFile.create(fmt.allocator, file_path); | |
| 380 | const baf = try io.BufferedAtomicFile.create(fmt.allocator, fs.cwd(), real_path, .{}); | |
| 374 | 381 | defer baf.destroy(); |
| 375 | 382 | |
| 376 | 383 | const anything_changed = try std.zig.render(fmt.allocator, baf.stream(), tree); |