Author SHA1 Message Date
Nyra ab2b8b798f Restore transcriber output silencing without shell interpolation
The argv form dropped the old &>/dev/null redirect, so the transcriber
output leaked to mpv terminal. Keep the command string a constant and
pass the paths as positional parameters: no interpolated shell input
(so a filename can not be parsed as shell syntax) while the redirect
that silenced the output is restored.

Verified end-to-end through the script, with the real binding and a
media file named evil$(touch PWNED).wav: argv arrived intact as a
single argument, LD_LIBRARY_PATH preserved, payload inert, no leak.
2026-09-27 07:50:32 +00:00
Codex (via nyra-lab) 3378ab4663 Fix silent callbacks and shell injection in export/transcribe scripts
mp.command_native second argument is a default return value, not a
completion callback: the callback was discarded, so exports never
reported success or failure and the synchronous subprocess blocked mpv.
Use mp.command_native_async at the four sites that pass a callback.

transcribe-subtitles built a bash -c string with the media path
interpolated, so a filename containing $(...) executed on trigger.
Pass argv directly, carry LD_LIBRARY_PATH via env, and replace the
trailing shell & with detach = true.

Verified on mpv 0.41.0: callback fires, hostile filename inert.
2026-09-27 07:44:22 +00:00
4 changed files with 14 additions and 8 deletions
+1 -1
View File
@@ -309,7 +309,7 @@ local function export_both()
end
for i, j in ipairs(jobs) do
mp.command_native({
mp.command_native_async({
name = "subprocess", args = j.args,
playback_only = false, capture_stdout = false, capture_stderr = false,
}, function(success, result, err)
+2 -2
View File
@@ -238,7 +238,7 @@ local function export_loop()
-- Only normal (no adjustments — skip making an identical duplicate)
osd_msg(string.format("Exporting loop (normal) ..."), 2)
mp.command_native({
mp.command_native_async({
name = "subprocess", args = normal_args,
playback_only = false, capture_stdout = false, capture_stderr = false,
}, function(success, result, err)
@@ -289,7 +289,7 @@ local function export_loop()
for i = 1, 2 do
local idx = i
local args = (idx == 1) and normal_args or modified_args
mp.command_native({
mp.command_native_async({
name = "subprocess", args = args,
playback_only = false, capture_stdout = false, capture_stderr = false,
}, function(success, result, err)
+1 -1
View File
@@ -142,7 +142,7 @@ local function capture_pair()
print(string.format("[screenshot-duo] Normal: %s", normal_path))
print(string.format("[screenshot-duo] Modified: %s", modified_path))
mp.command_native({
mp.command_native_async({
name = "subprocess",
args = ffmpeg_args,
playback_only = false,
+10 -4
View File
@@ -60,13 +60,19 @@ local function transcribe()
local transcriber = os.getenv("HOME") .. "/.local/bin/transcribe-video"
mp.osd_message("Transcribing subtitles ...", 1)
local shell_cmd = "export LD_LIBRARY_PATH=/opt/cuda/targets/x86_64-linux/lib; "
.. transcriber .. " --srt \"" .. abs_path .. "\" \"" .. srt_path .. "\" &>/dev/null &"
-- Silence the transcriber's output like the old `&>/dev/null` did, but WITHOUT handing a
-- shell an interpolated path: the command string below is a constant, and the paths travel
-- as positional parameters ($1, $2), so a filename can never be parsed as shell syntax.
mp.command_native({
name = "subprocess",
args = { "bash", "-c", shell_cmd },
args = {
"sh", "-c",
"exec \"$0\" --srt \"$1\" \"$2\" >/dev/null 2>&1",
transcriber, abs_path, srt_path,
},
env = { "LD_LIBRARY_PATH=/opt/cuda/targets/x86_64-linux/lib" },
playback_only = false,
detach = true,
})
poll_srt(srt_path, 0, 900)