From 788d1fa9d3a2cfadb9d1fd7081c1c558adcc946a Mon Sep 17 00:00:00 2001 From: Fahad Date: Tue, 10 Jun 2025 09:58:25 +0400 Subject: [PATCH] fix: prevent double translation of already-translated Docker paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added check in translate_path_for_environment() to detect and skip already-translated container paths (those starting with /workspace). This prevents the function from attempting to translate paths like: - /workspace/src/main.py -> /inaccessible/outside/mounted/volume/workspace/src/main.py Now it correctly handles: - Host path: /Users/.../src/main.py -> /workspace/src/main.py (translation) - Container path: /workspace/src/main.py -> /workspace/src/main.py (no change) Added comprehensive test to verify double-translation prevention. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- tests/test_docker_path_integration.py | 42 +++++++++++++++++++++++++++ utils/file_utils.py | 5 ++++ 2 files changed, 47 insertions(+) diff --git a/tests/test_docker_path_integration.py b/tests/test_docker_path_integration.py index 1d5f300..c1e67fc 100644 --- a/tests/test_docker_path_integration.py +++ b/tests/test_docker_path_integration.py @@ -237,5 +237,47 @@ def test_review_changes_docker_path_error(): importlib.reload(utils.file_utils) +def test_double_translation_prevention(): + """Test that already-translated paths are not double-translated""" + + with tempfile.TemporaryDirectory() as tmpdir: + # Set up directories + host_workspace = Path(tmpdir) / "host_workspace" + host_workspace.mkdir() + container_workspace = Path(tmpdir) / "container_workspace" + container_workspace.mkdir() + + original_env = os.environ.copy() + try: + os.environ["WORKSPACE_ROOT"] = str(host_workspace) + + # Reload the module + importlib.reload(utils.file_utils) + utils.file_utils.CONTAINER_WORKSPACE = container_workspace + + from utils.file_utils import translate_path_for_environment + + # Test 1: Normal translation + host_path = str(host_workspace / "src" / "main.py") + translated_once = translate_path_for_environment(host_path) + expected = str(container_workspace / "src" / "main.py") + assert translated_once == expected + + # Test 2: Double translation should return the same path + translated_twice = translate_path_for_environment(translated_once) + assert translated_twice == translated_once + assert translated_twice == expected + + # Test 3: Container workspace root should not be double-translated + root_path = str(container_workspace) + translated_root = translate_path_for_environment(root_path) + assert translated_root == root_path + + finally: + os.environ.clear() + os.environ.update(original_env) + importlib.reload(utils.file_utils) + + if __name__ == "__main__": pytest.main([__file__, "-v"]) diff --git a/utils/file_utils.py b/utils/file_utils.py index 6af9c19..d8b2e39 100644 --- a/utils/file_utils.py +++ b/utils/file_utils.py @@ -195,6 +195,11 @@ def translate_path_for_environment(path_str: str) -> str: # Not in the configured Docker environment, no translation needed return path_str + # Check if the path is already a container path (starts with /workspace) + if path_str.startswith(str(CONTAINER_WORKSPACE) + "/") or path_str == str(CONTAINER_WORKSPACE): + # Path is already translated to container format, return as-is + return path_str + try: # Use os.path.realpath for security - it resolves symlinks completely # This prevents symlink attacks that could escape the workspace