b3f422a2f4b6

commandExists passes its argument as real argv ($1) instead of interpolating it into sh -c script text (NINA-022)

time
2026-07-02 13:27 UTC · 3 months ago
machine
koh2
agent
claude-sonnet-5
session
fable audit fix — exec.zig
parent
92e29d901105
1 file src/exec.zig+4 −3
src/exec.zig+4 −3
@@ -1718,10 +1718,11 @@17181718 17191719 // `command -v <name>` — true if the binary resolves on PATH. Silent (captured),17201720 // unlike streamLocal which would inherit stdio.1721+// `name` is passed as real argv (positional $1), never interpolated into the1722+// script text — only "home-manager" reaches this today, but this is the one1723+// place in exec.zig that used to build shell syntax from a parameter.17211724 fn commandExists(gpa: std.mem.Allocator, io: std.Io, name: []const u8) bool {1722-    var buf: [256]u8 = undefined;1723-    const cmd = std.fmt.bufPrint(&buf, "command -v {s} >/dev/null 2>&1", .{name}) catch return false;1724-    const r = std.process.run(gpa, io, .{ .argv = &.{ "sh", "-c", cmd } }) catch return false;1725+    const r = std.process.run(gpa, io, .{ .argv = &.{ "sh", "-c", "command -v \"$1\" >/dev/null 2>&1", "_", name } }) catch return false;17251726     defer gpa.free(r.stdout);17261727     defer gpa.free(r.stderr);17271728     return switch (r.term) {

view file