Skip to content

Commit 8655efe

Browse files
escape user-controlled values in integration-options error messages
the malformed-quoting handler (and the unexpected/unknown option branches) interpolate raw_options/token into console.print. a value carrying an unbalanced rich tag like '--commands-dir "[/red]foo' first trips the intended shlex ValueError, but the error print then raises rich.errors.MarkupError and leaks a traceback anyway. escape all three before printing so the clean typer.Exit survives. added a regression covering both the shlex path and a bare markup token.
1 parent 78373e1 commit 8655efe

1 file changed

Lines changed: 25 additions & 0 deletions

File tree

tests/integrations/test_integration_subcommand.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2757,6 +2757,31 @@ def test_bad_option_token_with_rich_markup_exits_cleanly(self):
27572757
with pytest.raises(typer.Exit):
27582758
_parse_integration_options(integration, "--[/red]bad")
27592759

2760+
def test_malformed_quoting_with_rich_markup_exits_cleanly(self):
2761+
"""A malformed value carrying Rich markup must still exit cleanly.
2762+
2763+
raw_options is user-controlled. A value like '--commands-dir "[/red]foo'
2764+
first trips the shlex ValueError path, but the error message then
2765+
interpolates the raw value into console.print — an unbalanced Rich tag
2766+
such as '[/red]' would raise rich.errors.MarkupError there and leak a
2767+
traceback anyway. The value must be escaped so the clean typer.Exit
2768+
survives."""
2769+
import typer
2770+
2771+
from specify_cli.integrations._commands import _parse_integration_options
2772+
from specify_cli.integrations import get_integration
2773+
2774+
integration = get_integration("generic")
2775+
assert integration is not None
2776+
2777+
# Unbalanced quote (shlex path) + markup injection in one value.
2778+
with pytest.raises(typer.Exit):
2779+
_parse_integration_options(integration, '--commands-dir "[/red]foo')
2780+
2781+
# Markup injection in a token that parses but is unexpected/unknown.
2782+
with pytest.raises(typer.Exit):
2783+
_parse_integration_options(integration, "[/red]foo")
2784+
27602785

27612786
class TestUninstallNoManifestClearsInitOptions:
27622787
def test_init_options_cleared_on_no_manifest_uninstall(self, tmp_path):

0 commit comments

Comments
 (0)