




















@@ -0,0 +1,105 @@
1+import { describe, expect, it } from "vitest";
2+import {
3+hardenedEnvForChildOomWrap,
4+prepareOomScoreAdjustedSpawn,
5+wrapArgvForChildOomScoreRaise,
6+} from "./linux-oom-score.js";
7+8+const argv = ["/usr/bin/node", "--max-old-space-size=256", "run.js", "arg with spaces"];
9+const wrapScript = 'echo 1000 > /proc/self/oom_score_adj 2>/dev/null; exec "$0" "$@"';
10+const linux = { platform: "linux", env: {}, shellAvailable: () => true } as const;
11+const linuxNoShell = { platform: "linux", env: {}, shellAvailable: () => false } as const;
12+13+describe("wrapArgvForChildOomScoreRaise", () => {
14+it("wraps argv on linux with default env", () => {
15+const result = wrapArgvForChildOomScoreRaise(argv, linux);
16+expect(result.slice(0, 3)).toEqual(["/bin/sh", "-c", wrapScript]);
17+expect(result.slice(3)).toEqual(argv);
18+});
19+20+it("returns argv unchanged on non-linux platforms", () => {
21+for (const platform of ["darwin", "win32", "freebsd"] as const) {
22+expect(
23+wrapArgvForChildOomScoreRaise(argv, { platform, env: {}, shellAvailable: () => true }),
24+).toEqual(argv);
25+}
26+});
27+28+it("respects the OPENCLAW_CHILD_OOM_SCORE_ADJ opt-out", () => {
29+for (const value of ["0", "false", "FALSE", "no", "off"]) {
30+expect(
31+wrapArgvForChildOomScoreRaise(argv, {
32+ ...linux,
33+env: { OPENCLAW_CHILD_OOM_SCORE_ADJ: value },
34+}),
35+).toEqual(argv);
36+}
37+});
38+39+it("skips wrap when /bin/sh is unavailable (distroless/scratch)", () => {
40+expect(wrapArgvForChildOomScoreRaise(argv, linuxNoShell)).toEqual(argv);
41+});
42+43+it("does not double-wrap already-wrapped argv", () => {
44+const once = wrapArgvForChildOomScoreRaise(argv, linux);
45+const twice = wrapArgvForChildOomScoreRaise(once, linux);
46+expect(twice).toEqual(once);
47+});
48+49+it("returns empty argv unchanged", () => {
50+expect(wrapArgvForChildOomScoreRaise([], linux)).toEqual([]);
51+});
52+53+it("skips wrap for command names that exec could parse as options", () => {
54+expect(wrapArgvForChildOomScoreRaise(["-p", "node"], linux)).toEqual(["-p", "node"]);
55+});
56+});
57+58+describe("prepareOomScoreAdjustedSpawn", () => {
59+it("returns command, args, and hardened env when wrap applies", () => {
60+const result = prepareOomScoreAdjustedSpawn("/usr/bin/node", ["run.js"], {
61+ ...linux,
62+env: { PATH: "/usr/bin", BASH_ENV: "/tmp/bashenv", ENV: "/tmp/env", CDPATH: "/tmp" },
63+});
64+expect(result).toEqual({
65+command: "/bin/sh",
66+args: ["-c", wrapScript, "/usr/bin/node", "run.js"],
67+env: { PATH: "/usr/bin" },
68+wrapped: true,
69+});
70+});
71+72+it("preserves the spawn shape when wrap does not apply", () => {
73+const env = { PATH: "/usr/bin" };
74+expect(
75+prepareOomScoreAdjustedSpawn("/usr/bin/node", ["run.js"], {
76+platform: "darwin",
77+ env,
78+shellAvailable: () => true,
79+}),
80+).toEqual({
81+command: "/usr/bin/node",
82+args: ["run.js"],
83+ env,
84+wrapped: false,
85+});
86+});
87+});
88+89+describe("hardenedEnvForChildOomWrap", () => {
90+const tainted = { PATH: "/usr/bin", BASH_ENV: "/tmp/evil.sh", ENV: "/tmp/evil", CDPATH: "/tmp" };
91+92+it("strips shell-init keys when wrap applies", () => {
93+expect(hardenedEnvForChildOomWrap(tainted, linux)).toEqual({ PATH: "/usr/bin" });
94+});
95+96+it("preserves baseEnv (including undefined) when wrap does not apply", () => {
97+expect(hardenedEnvForChildOomWrap(tainted, linuxNoShell)).toBe(tainted);
98+expect(
99+hardenedEnvForChildOomWrap(undefined, { platform: "darwin", shellAvailable: () => true }),
100+).toBeUndefined();
101+expect(
102+hardenedEnvForChildOomWrap(tainted, { ...linux, env: { OPENCLAW_CHILD_OOM_SCORE_ADJ: "0" } }),
103+).toBe(tainted);
104+});
105+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。