Behavior-neutral structural pass over tools/*: god-file extractions into sibling modules (file_operations_common/lint/search, file_tools_paths/ read_tracking/write, code_execution_env/rpc, tool_search_catalog/names/ validation, tts_command_provider, ...), duplicate helper unification, if/elif -> dispatch tables, dead-code removal, docstring compaction. Tool schemas (get_tool_definitions) verified byte-identical to base.
25 lines
792 B
Python
25 lines
792 B
Python
"""Shared path validation helpers for tool implementations (skills, cron, credential files)."""
|
|
|
|
import logging
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def validate_within_dir(path: Path, root: Path) -> Optional[str]:
|
|
"""Return an error message if *path* does not resolve inside *root*, else None.
|
|
|
|
``Path.resolve()`` follows symlinks and normalises ``..`` before the check.
|
|
"""
|
|
try:
|
|
path.resolve().relative_to(root.resolve())
|
|
except (ValueError, OSError) as exc:
|
|
return f"Path escapes allowed directory: {exc}"
|
|
return None
|
|
|
|
|
|
def has_traversal_component(path_str: str) -> bool:
|
|
"""Cheap pre-check for a literal ``..`` component before full resolution."""
|
|
return ".." in Path(path_str).parts
|