diff options
author | 2022-11-03 23:22:51 -0700 | |
---|---|---|
committer | 2022-11-03 23:22:51 -0700 | |
commit | d6520cd761d79680576b516d27505865fe5376e5 (patch) | |
tree | c25dffadfd32b3b6617549f9afa273673eca16dd | |
parent | 13cfca481455a7822b0a478d88837f545e809b99 (diff) | |
download | bun-d6520cd761d79680576b516d27505865fe5376e5.tar.gz bun-d6520cd761d79680576b516d27505865fe5376e5.tar.zst bun-d6520cd761d79680576b516d27505865fe5376e5.zip |
Fix `which` not handling absolute paths to a bin
This code has not been tested.
-rw-r--r-- | src/which.zig | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/src/which.zig b/src/which.zig index 9303d6503..189bbce43 100644 --- a/src/which.zig +++ b/src/which.zig @@ -6,15 +6,32 @@ fn isValid(buf: *[bun.MAX_PATH_BYTES]u8, segment: []const u8, bin: []const u8) ? std.mem.copy(u8, buf[segment.len + 1 ..], bin); buf[segment.len + 1 + bin.len ..][0] = 0; const filepath = buf[0 .. segment.len + 1 + bin.len :0]; - // we cannot use access() here even though all we want to do now here is check it is executable - // directories can be considered executable - std.os.accessZ(filepath, std.os.X_OK) catch return null; + if (!checkPath(filepath)) return null; return @intCast(u16, filepath.len); } +fn checkPath(filepath: [:0]const u8) bool { + std.os.accessZ(filepath, std.os.X_OK) catch return false; + return true; +} + // Like /usr/bin/which but without needing to exec a child process // Remember to resolve the symlink if necessary pub fn which(buf: *[bun.MAX_PATH_BYTES]u8, path: []const u8, cwd: []const u8, bin: []const u8) ?[:0]const u8 { + if (bin.len == 0) return null; + + // handle absolute paths + if (std.fs.path.isAbsolute(bin)) { + std.mem.copy(u8, buf, bin); + buf[bin.len] = 0; + var binZ: [:0]u8 = buf[0..bin.len :0]; + if (checkPath(binZ)) return binZ; + + // note that directories are often executable + // TODO: should we return null here? What about the case where ytou have + // /foo/bar/baz as a path and you're in /home/jarred? + } + if (isValid(buf, std.mem.trimRight(u8, cwd, std.fs.path.sep_str), bin)) |len| { return buf[0..len :0]; } |