Harden open wrapper for Bash 3 and IDN host parity

This commit is contained in:
Lawrence Chen 2026-02-22 18:38:37 -08:00
parent 0046b674aa
commit 3afa345f3a
2 changed files with 176 additions and 18 deletions

View file

@ -65,21 +65,21 @@ fi
key="${3:-}"
case "$key" in
browserInterceptTerminalOpenCommandInCmuxBrowser)
if [[ -v FAKE_DEFAULTS_INTERCEPT_OPEN ]]; then
if [[ "${FAKE_DEFAULTS_INTERCEPT_OPEN+x}" == "x" ]]; then
printf '%s\\n' "$FAKE_DEFAULTS_INTERCEPT_OPEN"
exit 0
fi
exit 1
;;
browserOpenTerminalLinksInCmuxBrowser)
if [[ -v FAKE_DEFAULTS_LEGACY_OPEN ]]; then
if [[ "${FAKE_DEFAULTS_LEGACY_OPEN+x}" == "x" ]]; then
printf '%s\\n' "$FAKE_DEFAULTS_LEGACY_OPEN"
exit 0
fi
exit 1
;;
browserHostWhitelist)
if [[ -v FAKE_DEFAULTS_WHITELIST ]]; then
if [[ "${FAKE_DEFAULTS_WHITELIST+x}" == "x" ]]; then
printf '%s' "$FAKE_DEFAULTS_WHITELIST"
exit 0
fi
@ -97,7 +97,10 @@ esac
"""#!/usr/bin/env bash
set -euo pipefail
printf '%s\\n' "$*" >> "$FAKE_CMUX_LOG"
url="${*: -1}"
url=""
for arg in "$@"; do
url="$arg"
done
if [[ -n "${FAKE_CMUX_FAIL_URLS:-}" ]]; then
IFS=',' read -r -a failures <<< "$FAKE_CMUX_FAIL_URLS"
for fail_url in "${failures[@]}"; do
@ -139,7 +142,7 @@ exit 0
env.pop("FAKE_CMUX_FAIL_URLS", None)
result = subprocess.run(
[str(wrapper), *args],
["/bin/bash", str(wrapper), *args],
env=env,
capture_output=True,
text=True,
@ -166,6 +169,26 @@ def test_toggle_disabled_passthrough(failures: list[str]) -> None:
expect(open_log == [url], f"toggle off: expected system open [{url}], got {open_log}", failures)
def test_toggle_disabled_case_insensitive_passthrough(failures: list[str]) -> None:
url = "https://example.com"
open_log, cmux_log, code, stderr = run_wrapper(
args=[url],
intercept_setting=" FaLsE ",
whitelist="",
)
expect(code == 0, f"toggle off (case-insensitive): wrapper exited {code}: {stderr}", failures)
expect(
cmux_log == [],
f"toggle off (case-insensitive): cmux should not be called, got {cmux_log}",
failures,
)
expect(
open_log == [url],
f"toggle off (case-insensitive): expected system open [{url}], got {open_log}",
failures,
)
def test_whitelist_miss_passthrough(failures: list[str]) -> None:
url = "https://example.com"
open_log, cmux_log, code, stderr = run_wrapper(
@ -226,13 +249,75 @@ def test_legacy_toggle_fallback_passthrough(failures: list[str]) -> None:
expect(open_log == [url], f"legacy fallback: expected system open [{url}], got {open_log}", failures)
def test_legacy_toggle_fallback_case_insensitive_passthrough(failures: list[str]) -> None:
url = "https://example.com"
open_log, cmux_log, code, stderr = run_wrapper(
args=[url],
intercept_setting=None,
legacy_open_setting=" Off ",
whitelist="",
)
expect(code == 0, f"legacy fallback (case-insensitive): wrapper exited {code}: {stderr}", failures)
expect(
cmux_log == [],
f"legacy fallback (case-insensitive): cmux should not be called, got {cmux_log}",
failures,
)
expect(
open_log == [url],
f"legacy fallback (case-insensitive): expected system open [{url}], got {open_log}",
failures,
)
def test_uppercase_scheme_routes_to_cmux(failures: list[str]) -> None:
url = "HTTPS://api.example.com/path?q=1"
open_log, cmux_log, code, stderr = run_wrapper(
args=[url],
intercept_setting="1",
whitelist="*.example.com",
)
expect(code == 0, f"uppercase scheme: wrapper exited {code}: {stderr}", failures)
expect(open_log == [], f"uppercase scheme: system open should not be called, got {open_log}", failures)
expect(cmux_log == [f"browser open {url}"], f"uppercase scheme: unexpected cmux log {cmux_log}", failures)
def test_unicode_whitelist_matches_punycode_url(failures: list[str]) -> None:
url = "https://xn--bcher-kva.example/path"
open_log, cmux_log, code, stderr = run_wrapper(
args=[url],
intercept_setting="1",
whitelist="bücher.example",
)
expect(code == 0, f"unicode whitelist: wrapper exited {code}: {stderr}", failures)
expect(open_log == [], f"unicode whitelist: system open should not be called, got {open_log}", failures)
expect(cmux_log == [f"browser open {url}"], f"unicode whitelist: unexpected cmux log {cmux_log}", failures)
def test_punycode_whitelist_matches_unicode_url(failures: list[str]) -> None:
url = "https://bücher.example/path"
open_log, cmux_log, code, stderr = run_wrapper(
args=[url],
intercept_setting="1",
whitelist="xn--bcher-kva.example",
)
expect(code == 0, f"punycode whitelist: wrapper exited {code}: {stderr}", failures)
expect(open_log == [], f"punycode whitelist: system open should not be called, got {open_log}", failures)
expect(cmux_log == [f"browser open {url}"], f"punycode whitelist: unexpected cmux log {cmux_log}", failures)
def main() -> int:
failures: list[str] = []
test_toggle_disabled_passthrough(failures)
test_toggle_disabled_case_insensitive_passthrough(failures)
test_whitelist_miss_passthrough(failures)
test_whitelist_match_routes_to_cmux(failures)
test_partial_failures_only_fallback_failed_urls(failures)
test_legacy_toggle_fallback_passthrough(failures)
test_legacy_toggle_fallback_case_insensitive_passthrough(failures)
test_uppercase_scheme_routes_to_cmux(failures)
test_unicode_whitelist_matches_punycode_url(failures)
test_punycode_whitelist_matches_unicode_url(failures)
if failures:
print("open wrapper regression tests failed:")