fix: lifecycle guard crashes on referenced scripts with embedded NUL byte paths - #78506
fix: lifecycle guard crashes on referenced scripts with embedded NUL byte paths#78506Duncan822 wants to merge 2 commits into
Conversation
Duplicate of #77898: both patches catch the same embedded-NUL |
Second fix (same root cause, second symptom)After the first fix, the guard no longer crashes — but it now false-blocks commands that reference a binary in a script position (e.g. Cause
FixMirror the local NUL guard in the remote fallback: if the returned text contains Tests
|
|
Closing as duplicate of #77898 — the embedded-NUL Important follow-up: while testing this in production I found a second symptom of the same root cause that #77898 does not cover: after the crash is fixed, the guard false-blocks commands that reference a binary in a script position (e.g. I've posted the full fix (mirror the local NUL guard in the remote fallback) as a comment on #77898 with tests. Local copy of both fixes is active here. |
Bug
cron/lifecycle_guard.pycrashes withValueError: embedded null byteinside_read_referenced_scriptwhen a command references a script whose scanned contents yield a path containing a NUL byte.Observed on the
terminaltool: any command referencing certain scripts (e.g.python /home/user/scripts/bitaxe_thermal_guard.py) fails with:Root cause
_iter_referenced_shell_scriptscan yield a path containing an embedded NUL byte (binary/decoded content tokenized as a path — the exact case #76762 documents)._contains_unsafe_gateway_actionalready guardsscript_path.resolve()withexcept (OSError, ValueError)(lines 315-320), but then passes the originalscript_pathto_read_referenced_script, whoseos.openonly catchesOSError.os.openraisesValueErrorfor NUL-containing paths, which escapes and crashes the guard (and therefore the tool call).Fix
Catch
ValueErroralongsideOSErrorin_read_referenced_scriptand treat it as "nothing to scan" — consistent with the documented intent that a guarded path must never crash the guard.Test
_read_referenced_script(Path("/path/to/file\x00foo"))now returns(None, False)instead of raising.