Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion skills/fix-plan/scripts/hook_integrity_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ def resolve_script_operand(command):
resolves to `/path/hook.sh`, not to the interpreter.
"""
try:
tokens = shlex.split(command)
# posix=True (the default) treats backslash as an escape character,
# so a Windows path like C:\Users\... loses every backslash
# (\U -> U, \A -> A, ...) and the resolved path silently stops
# existing. posix=False keeps backslashes literal; the manual
# strip('"')/strip("'") calls below still handle quoting.
tokens = shlex.split(command, posix=(sys.platform != "win32"))
except ValueError:
tokens = command.split()
for tok in tokens:
Expand Down
18 changes: 18 additions & 0 deletions tests/test_hook_integrity_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,24 @@ def test_resolve_plain_path_unchanged():
assert mod.resolve_script_operand('"/p/with space/hook.sh"') == "/p/with space/hook.sh"


def test_resolve_preserves_windows_backslashes(monkeypatch):
# posix=True shlex.split treats backslash as an escape character, so a
# Windows path silently loses every backslash (\U -> U, \A -> A, ...)
# and the resolved path stops existing. Guards the fix for that.
# Force the win32 branch explicitly so this test is deterministic
# regardless of the platform actually running it (CI runs on Linux).
monkeypatch.setattr(mod.sys, "platform", "win32")
assert mod.resolve_script_operand(r"python3 C:\Users\me\hook.sh") == r"C:\Users\me\hook.sh"


def test_resolve_posix_path_unaffected_by_win32_branch(monkeypatch):
# On win32, posix=False is used -- confirm ordinary POSIX paths and
# interpreter/flag skipping still resolve correctly under that mode.
monkeypatch.setattr(mod.sys, "platform", "win32")
assert mod.resolve_script_operand("python3 /p/hook.sh") == "/p/hook.sh"
assert mod.resolve_script_operand('"/p/with space/hook.sh"') == "/p/with space/hook.sh"


# --- check_hook_integrity: end-to-end on the installed schema ---

def test_installed_schema_is_audited(tmp_path, monkeypatch):
Expand Down
Loading