Skip to content

Commit

Permalink
fix(ext/node): homedir() getpwuid/SHGetKnownFolderPath fallback (#…
Browse files Browse the repository at this point in the history
…23841)

**Unix**: Returns the value of the HOME environment variable if it is
set even if it is an empty string. Otherwise, it tries to determine the
home directory by invoking the
[getpwuid_r](https://linux.die.net/man/3/getpwuid_r) function with the
UID of the current user.

**Windows**: Returns the value of the USERPROFILE environment variable
if it is set and it is not an empty string. Otherwise, it tries to
determine the home directory by invoking the
[SHGetKnownFolderPath](https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath)
function with
[FOLDERID_Profile](https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid).

Fixes #23824
  • Loading branch information
littledivy committed May 16, 2024
1 parent a31b813 commit bba553b
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 17 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions ext/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ errno = "0.2.8"
faster-hex.workspace = true
h2 = { version = "0.3.26", features = ["unstable"] }
hkdf.workspace = true
home = "0.5.9"
http_v02.workspace = true
idna = "0.3.0"
indexmap.workspace = true
Expand Down
1 change: 1 addition & 0 deletions ext/node/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ deno_core::extension!(deno_node,
ops::os::op_node_os_username<P>,
ops::os::op_geteuid<P>,
ops::os::op_cpus<P>,
ops::os::op_homedir<P>,
op_node_build_os,
op_node_is_promise_rejected,
op_npm_process_state,
Expand Down
14 changes: 14 additions & 0 deletions ext/node/ops/os/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,17 @@ where

cpus::cpu_info().ok_or_else(|| type_error("Failed to get cpu info"))
}

#[op2]
#[string]
pub fn op_homedir<P>(state: &mut OpState) -> Result<Option<String>, AnyError>
where
P: NodePermissions + 'static,
{
{
let permissions = state.borrow_mut::<P>();
permissions.check_sys("homedir", "node:os.homedir()")?;
}

Ok(home::home_dir().map(|path| path.to_string_lossy().to_string()))
}
19 changes: 3 additions & 16 deletions ext/node/polyfills/os.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@

import {
op_cpus,
op_homedir,
op_node_os_get_priority,
op_node_os_set_priority,
op_node_os_username,
} from "ext:core/ops";

import { validateIntegerRange } from "ext:deno_node/_utils.ts";
import process from "node:process";
import { isWindows, osType } from "ext:deno_node/_util/os.ts";
import { isWindows } from "ext:deno_node/_util/os.ts";
import { ERR_OS_NO_HOMEDIR } from "ext:deno_node/internal/errors.ts";
import { os } from "ext:deno_node/internal_binding/constants.ts";
import { osUptime } from "ext:runtime/30_os.js";
Expand Down Expand Up @@ -173,21 +174,7 @@ export function getPriority(pid = 0): number {

/** Returns the string path of the current user's home directory. */
export function homedir(): string | null {
// Note: Node/libuv calls getpwuid() / GetUserProfileDirectory() when the
// environment variable isn't set but that's the (very uncommon) fallback
// path. IMO, it's okay to punt on that for now.
switch (osType) {
case "windows":
return Deno.env.get("USERPROFILE") || null;
case "linux":
case "android":
case "darwin":
case "freebsd":
case "openbsd":
return Deno.env.get("HOME") || null;
default:
throw Error("unreachable");
}
return op_homedir();
}

/** Returns the host name of the operating system as a string. */
Expand Down
2 changes: 1 addition & 1 deletion runtime/permissions/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,7 @@ impl Descriptor for SysDescriptor {
pub fn parse_sys_kind(kind: &str) -> Result<&str, AnyError> {
match kind {
"hostname" | "osRelease" | "osUptime" | "loadavg" | "networkInterfaces"
| "systemMemoryInfo" | "uid" | "gid" | "cpus" => Ok(kind),
| "systemMemoryInfo" | "uid" | "gid" | "cpus" | "homedir" => Ok(kind),
_ => Err(type_error(format!("unknown system info kind \"{kind}\""))),
}
}
Expand Down
8 changes: 8 additions & 0 deletions tests/unit_node/os_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ Deno.test({
},
});

Deno.test({
name: "home directory when HOME is not set",
fn() {
Deno.env.delete("HOME");
assertEquals(typeof os.homedir(), "string");
},
});

Deno.test({
name: "tmp directory is a string",
fn() {
Expand Down

0 comments on commit bba553b

Please sign in to comment.