From 99b140c20d7f301425ea0dd86762d8cd520fd605 Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Thu, 5 Mar 2020 20:15:55 -0800 Subject: [PATCH] fmt: Fix relative paths with . and .. on Windows This is a band-aid fix due to NtCreateFile failing on paths with . or .. in them. --- src-self-hosted/stage2.zig | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index fcf9634097b7..6c5287067228 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -315,11 +315,18 @@ const FmtError = error{ } || fs.File.OpenError; fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { - if (fmt.seen.exists(file_path)) return; - try fmt.seen.put(file_path); + // get the real path here to avoid Windows failing on relative file paths with . or .. in them + var real_path = fs.realpathAlloc(fmt.allocator, file_path) catch |err| { + try stderr.print("unable to open '{}': {}\n", .{ file_path, err }); + fmt.any_error = true; + return; + }; + defer fmt.allocator.free(real_path); + + if (fmt.seen.exists(real_path)) return; + try fmt.seen.put(real_path); - const max = std.math.maxInt(usize); - const source_code = fs.cwd().readFileAlloc(fmt.allocator, file_path, max) catch |err| switch (err) { + const source_code = fs.cwd().readFileAlloc(fmt.allocator, real_path, self_hosted_main.max_src_size) catch |err| switch (err) { error.IsDir, error.AccessDenied => { // TODO make event based (and dir.next()) var dir = try fs.cwd().openDir(file_path, .{ .iterate = true }); @@ -329,7 +336,7 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { while (try dir_it.next()) |entry| { if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) { - const full_path = try fs.path.join(fmt.allocator, &[_][]const u8{ file_path, entry.name }); + const full_path = try fs.path.join(fmt.allocator, &[_][]const u8{ real_path, entry.name }); try fmtPath(fmt, full_path, check_mode); } } @@ -367,7 +374,7 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { fmt.any_error = true; } } else { - const baf = try io.BufferedAtomicFile.create(fmt.allocator, file_path); + const baf = try io.BufferedAtomicFile.create(fmt.allocator, real_path); defer baf.destroy(); const anything_changed = try std.zig.render(fmt.allocator, baf.stream(), tree);