diff --git a/src/cleveragents/cli.py b/src/cleveragents/cli.py index 91089ff51..00fa8ffaa 100644 --- a/src/cleveragents/cli.py +++ b/src/cleveragents/cli.py @@ -87,9 +87,40 @@ def run( sys.exit(1) if output: - with output.open("w") as f: - f.write(result) - click.echo(f"Output written to {output}") + # Validate and safely write output file + try: + output_path = output.resolve() + + # Block system directories + system_dirs = ['/etc', '/sys', '/proc', '/dev', '/boot', '/root'] + for sys_dir in system_dirs: + if str(output_path).startswith(sys_dir): + click.echo( + f"Error: Cannot write to system directory: {sys_dir}", + err=True + ) + sys.exit(1) + + # Confirm overwrite if file exists + if output_path.exists(): + if not click.confirm( + f"File '{output_path}' already exists. Overwrite?", + default=False + ): + click.echo("Cancelled.") + sys.exit(0) + + # Create parent directory if needed + output_path.parent.mkdir(parents=True, exist_ok=True) + + # Write file + with output.open("w") as f: + f.write(result) + click.echo(f"Output written to {output}") + + except Exception as e: + click.echo(f"Error writing output file: {e}", err=True) + sys.exit(1) else: click.echo(result) diff --git a/tests/unit/test_cli.py b/tests/unit/test_cli.py index c16303f1f..94323289d 100644 --- a/tests/unit/test_cli.py +++ b/tests/unit/test_cli.py @@ -4,9 +4,10 @@ Unit tests for cli.py module Tests the command-line interface for CleverAgents. """ +import os import pytest from pathlib import Path -from unittest.mock import Mock, patch, AsyncMock, MagicMock +from unittest.mock import Mock, patch from click.testing import CliRunner import tempfile @@ -157,8 +158,8 @@ class TestRunCommand: mock_app_class.return_value = mock_app mock_asyncio_run.return_value = "Test result" - with tempfile.NamedTemporaryFile(mode='w', prefix='cleveragent_', delete=False) as output_file: - output_path = Path(output_file.name) + # Generate path to a non-existent file to avoid overwrite confirmation prompt + output_path = Path(tempfile.gettempdir()) / f'cleveragent_test_{os.getpid()}_{id(self)}.txt' try: result = runner.invoke(run, [