26454ed98d54
runHook quotes $1 in its sh -c runner script so a hook path containing spaces or glob characters runs correctly (NINA-010)
- time
- 2026-07-02 13:26 UTC · 3 months ago
- machine
- koh2
- agent
- claude-sonnet-5
- session
- fable audit fix — exec.zig
- parent
- d4dd5ae4eb6e
↓ nina-26454ed9.tar.gzatlas at this save
files changed1 file
src/exec.zig+20 −1src/exec.zig+20 −1
@@ -224,7 +224,7 @@224224 .argv = &.{225225 "sh",226226 "-c",227- "$1 > \"$2\" 2>&1; code=$?; tail -c 4096 \"$2\"; exit \"$code\"",227+ "\"$1\" > \"$2\" 2>&1; code=$?; tail -c 4096 \"$2\"; exit \"$code\"",228228 "nina-hook-run",229229 hook_path,230230 tmp_output,@@ -289,6 +289,25 @@289289 try std.testing.expectEqual(@as(u8, 3), failed.exit_code);290290 try std.testing.expect(std.mem.indexOf(u8, failed.output, "hook says no") != null);291291 try std.testing.expect(std.mem.indexOf(u8, failed.output, "detail") != null);292+293+ // NINA-010: the runner script's `$1` (the hook path) must be quoted — a294+ // hook whose path contains a space used to word-split and fail to run.295+ const spaced_script =296+ \\#!/bin/sh297+ \\echo spaced hook ran298+ \\exit 0299+ \\300+ ;301+ {302+ const file = try hook_dir.createFile(io, "post apply", .{});303+ defer file.close(io);304+ try file.writePositionalAll(io, spaced_script, 0);305+ try file.setPermissions(io, .fromMode(0o755));306+ }307+ const spaced = try runHook(a, io, &env, "post apply");308+ defer a.free(spaced.output);309+ try std.testing.expectEqual(HookResult.ok, spaced.result);310+ try std.testing.expect(std.mem.indexOf(u8, spaced.output, "spaced hook ran") != null);292311 }293312 294313 // Single-quote-wrap `arg` for a POSIX shell, escaping embedded single quotes as