From 03a3c0f93623757e925c981711e0f7fafdfd98bf Mon Sep 17 00:00:00 2001 From: Ramesh Padmanabhaiah <22363102+codeforester@users.noreply.github.com> Date: Sat, 8 Aug 2026 13:09:02 -0700 Subject: [PATCH] Validate control line breaks in test manifests --- cli/python/base_setup/manifest.py | 4 +++ cli/python/base_setup/tests/test_manifest.py | 26 ++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/cli/python/base_setup/manifest.py b/cli/python/base_setup/manifest.py index 6d054c5a..7bbd9ad1 100644 --- a/cli/python/base_setup/manifest.py +++ b/cli/python/base_setup/manifest.py @@ -191,6 +191,10 @@ def _read_test(path: Path, test_data: Any) -> TestConfig | None: raise ManifestError(f"{path}: test.command must be a non-empty string when provided.") if mise is not None and (not isinstance(mise, str) or not mise.strip()): raise ManifestError(f"{path}: test.mise must be a non-empty string when provided.") + if command is not None and has_control_line_break(command): + raise ManifestError(f"{path}: test.command must not contain control line breaks.") + if mise is not None and has_control_line_break(mise): + raise ManifestError(f"{path}: test.mise must not contain control line breaks.") if command is not None and mise is not None: raise ManifestError(f"{path}: test must declare only one of command or mise.") if command is None and mise is None: diff --git a/cli/python/base_setup/tests/test_manifest.py b/cli/python/base_setup/tests/test_manifest.py index 082a9b8b..da6b2256 100644 --- a/cli/python/base_setup/tests/test_manifest.py +++ b/cli/python/base_setup/tests/test_manifest.py @@ -1059,6 +1059,32 @@ def test_rejects_invalid_manifest_test_command(self) -> None: read_manifest(manifest_path) + def test_rejects_control_line_breaks_in_manifest_test_command_or_mise(self) -> None: + for field_name in ("command", "mise"): + for escaped_control_break in (r"\0", r"\n", r"\r"): + with self.subTest(field_name=field_name, escaped_control_break=escaped_control_break): + with tempfile.TemporaryDirectory() as tmpdir: + manifest_path = Path(tmpdir) / "base_manifest.yaml" + manifest_path.write_text( + "\n".join( + [ + "project:", + " name: demo", + "test:", + f' {field_name}: "test{escaped_control_break}command"', + "artifacts: []", + ] + ), + encoding="utf-8", + ) + + with self.assertRaisesRegex( + ManifestError, + rf"test\.{field_name} must not contain control line breaks", + ): + read_manifest(manifest_path) + + def test_rejects_invalid_manifest_test_runner(self) -> None: with tempfile.TemporaryDirectory() as tmpdir: manifest_path = Path(tmpdir) / "base_manifest.yaml"