Capture exact filesystem identity and nanosecond timestamps, validate descriptor/path state before and after streaming, and enforce the captured byte count. Bound growing files to their captured size plus one byte using precise positional reads; keep unrepresentable display sizes explicitly unknown. Reuse the captured-state comparison around Apple assetutil and retain existing reader cleanup ownership. Validation: focused reader and affected consumer suites, full static/architecture checks, and a compiled directory-read probe on Bun 1.3.14 passed. Includes same-size mutation, growth, truncation, cancellation, FIFO replacement, cleanup retry, ZIP identity forgery, ASAR and Mach-O coverage.
25 lines
945 B
TypeScript
25 lines
945 B
TypeScript
import type { BigIntStats, Stats } from "node:fs";
|
|
import { extname } from "node:path";
|
|
|
|
/** Extensions Windows launches directly through CreateProcess or cmd.exe. */
|
|
const windowsLaunchableExtensions = new Set([".bat", ".cmd", ".com", ".exe"]);
|
|
|
|
/**
|
|
* Whether a host filesystem entry carries the host's executable marking.
|
|
*
|
|
* POSIX hosts mark executability with permission bits. Windows has no execute
|
|
* bit (Node reports file modes from the read-only attribute alone), so it marks
|
|
* launchable files by extension instead.
|
|
*/
|
|
export const hostExecutableMarking = (
|
|
path: string,
|
|
metadata: Pick<Stats | BigIntStats, "mode" | "isFile">,
|
|
platform: NodeJS.Platform = process.platform,
|
|
): boolean =>
|
|
platform === "win32"
|
|
? metadata.isFile() &&
|
|
windowsLaunchableExtensions.has(extname(path).toLowerCase())
|
|
: typeof metadata.mode === "bigint"
|
|
? (metadata.mode & 0o111n) !== 0n
|
|
: (metadata.mode & 0o111) !== 0;
|