Skip to content

Commit

Permalink
Lower permission requirement of which, by replacing access with stat.
Browse files Browse the repository at this point in the history
  • Loading branch information
Hexagon committed Mar 30, 2024
1 parent b7f8973 commit 9c86303
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
4 changes: 2 additions & 2 deletions deno.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cross/fs",
"version": "0.0.7",
"version": "0.0.8",
"exports": {
".": "./mod.ts",
"./stat": "./src/stat/mod.ts",
Expand All @@ -12,7 +12,7 @@
"@cross/env": "jsr:@cross/env@^1.0.0",
"@cross/runtime": "jsr:@cross/runtime@^1.0.0",
"@cross/test": "jsr:@cross/test@^0.0.9",
"@cross/utils": "jsr:@cross/utils@^0.8.2",
"@cross/utils": "jsr:@cross/utils@^0.9.0",
"@std/assert": "jsr:@std/assert@^0.221.0",
"@std/path": "jsr:@std/path@^0.221.0"
},
Expand Down
18 changes: 15 additions & 3 deletions src/stat/which.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { access, constants } from "./mod.ts";
import { constants, stat } from "./mod.ts";
import { getEnv } from "@cross/env";
import { join } from "@std/path";

/**
* Searches for an executable file within the directories specified by the "PATH" environment variable.
*
* Uses stat to check if anyone (as apposed to the current user) has execute permission on the found executable, to avoid getting the current user id, which require higher permission in certain runtimes.
*
* @param command - The name of the executable file to locate.
* @returns The full path to the executable if found, otherwise null.
*/
Expand All @@ -14,8 +16,18 @@ export async function which(command: string): Promise<string | null> {
for (const dir of paths) {
const fullPath = join(dir, command);
try {
await access(fullPath, constants.X_OK); // Check if executable
return fullPath;
const fileInfo = await stat(fullPath);
// Soft Permission Check: Check if anyone has execute permission
if (
fileInfo && fileInfo.mode &&
(
(fileInfo.mode & constants.S_IXOTH) ||
(fileInfo.mode & constants.S_IXUSR) ||
(fileInfo.mode & constants.S_IXGRP)
)
) {
return fullPath;
}
} catch (_err) {
// Ignore and try the next path
}
Expand Down

0 comments on commit 9c86303

Please sign in to comment.