History

test: skip symlink fixtures where the host cannot create symlinks (#9566)

Julius Marminge committed 2 months ago

Commit 30f128f1 parent 470104120 files · +1035 −902Browse files

Showing the changes to apps/server/src/orchestration/workflowScriptQuery.test.ts (1 of 20 files). Show all

Unified · Split

apps/server/src/orchestration/workflowScriptQuery.test.ts+27−28
@@ -5,6 +5,7 @@ import * as NodePath from "node:path"; · 4 unmodified lines
5import { it as effectIt } from "@effect/vitest";5import { it as effectIt } from "@effect/vitest";
6import * as Effect from "effect/Effect";6import * as Effect from "effect/Effect";
7import { afterAll, assert, describe } from "vite-plus/test";7import { afterAll, assert, describe } from "vite-plus/test";
8import { symlinksSupported } from "@t3tools/shared/testing/symlinks";
8import { readWorkflowScript } from "./workflowScriptQuery.ts";9import { readWorkflowScript } from "./workflowScriptQuery.ts";
9 10
10const root = NodePath.join(NodeOS.homedir(), ".claude", "projects", "__wf_script_test__");11const root = NodePath.join(NodeOS.homedir(), ".claude", "projects", "__wf_script_test__");
@@ -14,19 +15,15 @@ NodeFS.writeFileSync(scriptPath, "export const meta = {};\n"); · 3 unmodified lines
14const outside = NodePath.join(NodeOS.tmpdir(), "wf-outside.js");15const outside = NodePath.join(NodeOS.tmpdir(), "wf-outside.js");
15NodeFS.writeFileSync(outside, "evil\n");16NodeFS.writeFileSync(outside, "evil\n");
16const link = NodePath.join(root, "sneaky.js");17const link = NodePath.join(root, "sneaky.js");
17try {18// Planted only where the host allows it; the escape test is skipped
19// otherwise rather than passing vacuously on "not-found".
20if (symlinksSupported) {
21 NodeFS.rmSync(link, { force: true });
18 NodeFS.symlinkSync(outside, link);22 NodeFS.symlinkSync(outside, link);
19} catch (error) {23 if (!NodeFS.lstatSync(link).isSymbolicLink()) {
20 // Tolerate only "already exists" from a prior run — any other failure24 throw new Error("test setup: sneaky.js must be a symlink");
21 // (EPERM etc.) must fail setup, or the escape test below would pass
22 // vacuously on "not-found" without testing containment.
23 if ((error as NodeJS.ErrnoException).code !== "EEXIST") {
24 throw error;
25 }25 }
26}26}
27if (!NodeFS.lstatSync(link).isSymbolicLink()) {
28 throw new Error("test setup: sneaky.js must be a symlink");
29}
30 27
31afterAll(() => {28afterAll(() => {
32 NodeFS.rmSync(root, { recursive: true, force: true });29 NodeFS.rmSync(root, { recursive: true, force: true });
@@ -53,23 +50,25 @@ describe("readWorkflowScript containment", () => { · 20 unmodified lines
53 }),50 }),
54 );51 );
55 52
56 effectIt.effect("rejects paths outside the root and symlink escapes", () =>53 effectIt.effect.skipIf(!symlinksSupported)(
57 Effect.gen(function* () {54 "rejects paths outside the root and symlink escapes",
58 const escaped = yield* Effect.exit(readWorkflowScript({ scriptPath: outside }));55 () =>
59 assert.equal(escaped._tag, "Failure");56 Effect.gen(function* () {
60 // A symlink INSIDE the root pointing outside must fail specifically on57 const escaped = yield* Effect.exit(readWorkflowScript({ scriptPath: outside }));
61 // realpath re-containment — a "not-found" would mean the link was58 assert.equal(escaped._tag, "Failure");
62 // never exercised and the assertion proves nothing.59 // A symlink INSIDE the root pointing outside must fail specifically on
63 const sneaky = yield* Effect.exit(60 // realpath re-containment — a "not-found" would mean the link was
64 readWorkflowScript({ scriptPath: link }).pipe(61 // never exercised and the assertion proves nothing.
65 Effect.flip,62 const sneaky = yield* Effect.exit(
66 Effect.map((error) => error.reason),63 readWorkflowScript({ scriptPath: link }).pipe(
67 ),64 Effect.flip,
68 );65 Effect.map((error) => error.reason),
69 assert.equal(sneaky._tag, "Success");66 ),
70 if (sneaky._tag === "Success") {67 );
71 assert.equal(sneaky.value, "outside-root");68 assert.equal(sneaky._tag, "Success");
72 }69 if (sneaky._tag === "Success") {
73 }),70 assert.equal(sneaky.value, "outside-root");
71 }
72 }),
74 );73 );
75});74});