From acf1b6735cf8e7f77a3af9eee3b559e8cbc6ffd4 Mon Sep 17 00:00:00 2001 From: bhuvan-somisetty Date: Mon, 21 Sep 2026 07:45:57 +0530 Subject: [PATCH] fix(cli): reject path-like project names in init --- concore_cli/commands/init.py | 7 +++++++ tests/test_cli.py | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/concore_cli/commands/init.py b/concore_cli/commands/init.py index 53fd53f..cfaf73c 100644 --- a/concore_cli/commands/init.py +++ b/concore_cli/commands/init.py @@ -258,8 +258,14 @@ def _build_graphml(project_name, selected_langs): # --------------------------------------------------------------------------- +def _check_project_name(name): + if name in (".", "..") or Path(name).name != name: + raise ValueError("Project name must not contain path separators") + + def init_project_interactive(name, selected_langs, console): """Create a project with one node per selected language (no edges).""" + _check_project_name(name) project_path = Path(name) if project_path.exists(): @@ -327,6 +333,7 @@ def init_project_interactive(name, selected_langs, console): def init_project(name, template, console): """Non-interactive init — single Python node skeleton.""" + _check_project_name(name) project_path = Path(name) if project_path.exists(): diff --git a/tests/test_cli.py b/tests/test_cli.py index d746040..ad832a4 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -55,6 +55,15 @@ def test_init_existing_directory(self): self.assertNotEqual(result.exit_code, 0) self.assertIn("already exists", result.output) + def test_init_rejects_path_in_name(self): + with self.runner.isolated_filesystem(temp_dir=self.temp_dir): + Path("work").mkdir() + os.chdir("work") + result = self.runner.invoke(cli, ["init", "../x"]) + self.assertNotEqual(result.exit_code, 0) + self.assertIn("path separators", result.output) + self.assertFalse(Path("../x").exists()) + def test_validate_missing_file(self): result = self.runner.invoke(cli, ["validate", "nonexistent.graphml"]) self.assertNotEqual(result.exit_code, 0)