diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-11-25 17:12:50 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-11-28 01:23:39 -0500 |
| commit | 3ae4931dc1a3b1b338d2fd3a49a5a79b445bebf6 (patch) | |
| tree | 8c6f031412192a2024f17506a8f9d10e0fd13343 /src/Module.zig | |
| parent | 7411be3c9e6d169108456f03b3cbb9b476ee7498 (diff) | |
| download | zig-3ae4931dc1a3b1b338d2fd3a49a5a79b445bebf6.tar.gz zig-3ae4931dc1a3b1b338d2fd3a49a5a79b445bebf6.zip | |
CLI: more careful resolution of paths
In general, we prefer compiler code to use relative paths based on open
directory handles because this is the most portable. However, sometimes
absolute paths are used, and sometimes relative paths are used that go
up a directory.
The recent improvements in 81d2135ca6ebd71b8c121a19957c8fbf7f87125b
regressed the use case when an absolute path is used for the zig lib
directory mixed with a relative path used for the root source file. This
could happen when, for example, running the standard library tests, like
this:
stage3/bin/zig test ../lib/std/std.zig
This happened because the zig lib dir was inferred to be an absolute
directory based on the zig executable directory, while the root source
file was detected as a relative path. There was no common prefix and so
it was not determined that the std.zig file was inside the lib
directory.
This commit adds a function for resolving paths that preserves relative
path names while allowing absolute paths, and converting relative
upwards paths (e.g. "../foo") to absolute paths. This restores the
previous functionality while remaining compatible with systems such as
WASI that cannot deal with absolute paths.
Diffstat (limited to 'src/Module.zig')
| -rw-r--r-- | src/Module.zig | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/src/Module.zig b/src/Module.zig index b7930615c8..8c45fc233f 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -30,6 +30,7 @@ const Sema = @import("Sema.zig"); const target_util = @import("target.zig"); const build_options = @import("build_options"); const Liveness = @import("Liveness.zig"); +const isUpDir = @import("introspect.zig").isUpDir; /// General-purpose allocator. Used for both temporary and long-term storage. gpa: Allocator, @@ -4957,15 +4958,19 @@ pub fn importFile( const resolved_root_path = try std.fs.path.resolve(gpa, &[_][]const u8{cur_pkg_dir_path}); defer gpa.free(resolved_root_path); - if (!mem.startsWith(u8, resolved_path, resolved_root_path) or - // This prevents this check from triggering when the name of the - // imported file starts with the root path's directory name. - !std.fs.path.isSep(resolved_path[resolved_root_path.len])) - { + const sub_file_path = p: { + if (mem.startsWith(u8, resolved_path, resolved_root_path)) { + // +1 for the directory separator here. + break :p try gpa.dupe(u8, resolved_path[resolved_root_path.len + 1 ..]); + } + if (mem.eql(u8, resolved_root_path, ".") and + !isUpDir(resolved_path) and + !std.fs.path.isAbsolute(resolved_path)) + { + break :p try gpa.dupe(u8, resolved_path); + } return error.ImportOutsidePkgPath; - } - // +1 for the directory separator here. - const sub_file_path = try gpa.dupe(u8, resolved_path[resolved_root_path.len + 1 ..]); + }; errdefer gpa.free(sub_file_path); log.debug("new importFile. resolved_root_path={s}, resolved_path={s}, sub_file_path={s}, import_string={s}", .{ @@ -5015,11 +5020,19 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb const resolved_root_path = try std.fs.path.resolve(gpa, &[_][]const u8{cur_pkg_dir_path}); defer gpa.free(resolved_root_path); - if (!mem.startsWith(u8, resolved_path, resolved_root_path)) { + const sub_file_path = p: { + if (mem.startsWith(u8, resolved_path, resolved_root_path)) { + // +1 for the directory separator here. + break :p try gpa.dupe(u8, resolved_path[resolved_root_path.len + 1 ..]); + } + if (mem.eql(u8, resolved_root_path, ".") and + !isUpDir(resolved_path) and + !std.fs.path.isAbsolute(resolved_path)) + { + break :p try gpa.dupe(u8, resolved_path); + } return error.ImportOutsidePkgPath; - } - // +1 for the directory separator here. - const sub_file_path = try gpa.dupe(u8, resolved_path[resolved_root_path.len + 1 ..]); + }; errdefer gpa.free(sub_file_path); var file = try cur_file.pkg.root_src_directory.handle.openFile(sub_file_path, .{}); |
