























@@ -965,22 +965,127 @@ describe("hardenApprovedExecutionPaths", () => {
965965});
966966967967it("captures the real shell script operand after value-taking shell flags", () => {
968-const tmp = createFixtureDir("openclaw-shell-option-value-");
969-const scriptPath = path.join(tmp, "run.sh");
970-fs.writeFileSync(scriptPath, "#!/bin/sh\necho SAFE\n");
971-fs.writeFileSync(path.join(tmp, "errexit"), "decoy\n");
972-const snapshot = resolveMutableFileOperandSnapshotSync({
973-argv: ["/bin/bash", "-o", "errexit", "./run.sh"],
974-cwd: tmp,
975-shellCommand: null,
976-});
977-expect(snapshot).toEqual({
978-ok: true,
979-snapshot: {
980-argvIndex: 3,
981-path: fs.realpathSync(scriptPath),
982-sha256: sha256FileSync(scriptPath),
968+const cases = [
969+{
970+name: "separate set option",
971+argv: ["/bin/bash", "-o", "errexit", "./run.sh"],
972+decoyName: "errexit",
973+expectedArgvIndex: 3,
983974},
984-});
975+{
976+name: "combined set option",
977+argv: ["/bin/bash", "-eo", "pipefail", "./run.sh"],
978+decoyName: "pipefail",
979+expectedArgvIndex: 3,
980+},
981+{
982+name: "combined trace option",
983+argv: ["/bin/bash", "-xo", "errexit", "./run.sh"],
984+decoyName: "errexit",
985+expectedArgvIndex: 3,
986+},
987+{
988+name: "combined unset option",
989+argv: ["/bin/bash", "-uo", "nounset", "./run.sh"],
990+decoyName: "nounset",
991+expectedArgvIndex: 3,
992+},
993+{
994+name: "plus set option",
995+argv: ["/bin/bash", "+o", "histexpand", "./run.sh"],
996+decoyName: "histexpand",
997+expectedArgvIndex: 3,
998+},
999+{
1000+name: "plus shopt option",
1001+argv: ["/bin/bash", "+O", "extglob", "./run.sh"],
1002+decoyName: "extglob",
1003+expectedArgvIndex: 3,
1004+},
1005+{
1006+name: "combined plus set option",
1007+argv: ["/bin/bash", "+eo", "pipefail", "./run.sh"],
1008+decoyName: "pipefail",
1009+expectedArgvIndex: 3,
1010+},
1011+];
1012+1013+for (const testCase of cases) {
1014+runNamedCase(testCase.name, () => {
1015+const tmp = createFixtureDir("openclaw-shell-option-value-");
1016+const scriptPath = path.join(tmp, "run.sh");
1017+fs.writeFileSync(scriptPath, "#!/bin/sh\necho SAFE\n");
1018+fs.writeFileSync(path.join(tmp, testCase.decoyName), "decoy\n");
1019+const snapshot = resolveMutableFileOperandSnapshotSync({
1020+argv: testCase.argv,
1021+cwd: tmp,
1022+shellCommand: null,
1023+});
1024+expect(snapshot).toEqual({
1025+ok: true,
1026+snapshot: {
1027+argvIndex: testCase.expectedArgvIndex,
1028+path: fs.realpathSync(scriptPath),
1029+sha256: sha256FileSync(scriptPath),
1030+},
1031+});
1032+if (!snapshot.ok || snapshot.snapshot === null) {
1033+throw new Error("expected mutable file operand snapshot");
1034+}
1035+fs.writeFileSync(scriptPath, "#!/bin/sh\necho CHANGED\n");
1036+expect(
1037+revalidateApprovedMutableFileOperand({
1038+snapshot: snapshot.snapshot,
1039+argv: testCase.argv,
1040+cwd: tmp,
1041+}),
1042+).toBe(false);
1043+});
1044+}
1045+});
1046+1047+it("captures fish script operands with plus-prefixed filenames", () => {
1048+const cases = [
1049+{
1050+name: "plus-prefixed fish script",
1051+argv: ["fish", "+setup.fish"],
1052+},
1053+{
1054+name: "plus-prefixed fish script before script args",
1055+argv: ["fish", "+setup.fish", "-c", "echo arg"],
1056+},
1057+];
1058+1059+for (const testCase of cases) {
1060+runNamedCase(testCase.name, () => {
1061+const tmp = createFixtureDir("openclaw-fish-plus-script-");
1062+const scriptPath = path.join(tmp, "+setup.fish");
1063+fs.writeFileSync(scriptPath, "echo SAFE\n");
1064+const snapshot = resolveMutableFileOperandSnapshotSync({
1065+argv: testCase.argv,
1066+cwd: tmp,
1067+shellCommand: null,
1068+});
1069+expect(snapshot).toEqual({
1070+ok: true,
1071+snapshot: {
1072+argvIndex: 1,
1073+path: fs.realpathSync(scriptPath),
1074+sha256: sha256FileSync(scriptPath),
1075+},
1076+});
1077+if (!snapshot.ok || snapshot.snapshot === null) {
1078+throw new Error("expected mutable file operand snapshot");
1079+}
1080+fs.writeFileSync(scriptPath, "echo CHANGED\n");
1081+expect(
1082+revalidateApprovedMutableFileOperand({
1083+snapshot: snapshot.snapshot,
1084+argv: testCase.argv,
1085+cwd: tmp,
1086+}),
1087+).toBe(false);
1088+});
1089+}
9851090});
9861091});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。