Skip to content

fix(tools): use path containment in find_files instead of a string pr… - #116

Open
ElectLive wants to merge 1 commit into
knight22-21:mainfrom
ElectLive:fix/find-files-containment
Open

ElectLive wants to merge 1 commit into
knight22-21:mainfrom
ElectLive:fix/find-files-containment

Conversation

@ElectLive

Copy link
Copy Markdown

What does this PR do?

find_files() now checks containment with Path.is_relative_to() instead of a string prefix, so a sibling directory whose name starts with the project root's name can no longer be searched.

Fixes #114

Root cause / motivation

search_root = (root / path).resolve()
if not str(search_root).startswith(str(root)):
    return "[error] path escapes project root"

/srv/project-private starts with /srv/project without being inside it, so find_files({"path": "../project-private"}) was allowed and listed files outside the project. This is the same pattern file_tools._within_roots() already fixed with is_relative_to(); the search tool kept the old spelling.

Changes

  • devagent/tools/search_tools.py: containment check is now search_root.is_relative_to(root), with a comment pointing at the rule file_tools uses.
  • tests/test_search_tool_containment.py: new regression tests — a name-prefix sibling is rejected, plain .. traversal is rejected, and files inside the project are still listed.

Test plan

pytest tests/test_search_tool_containment.py tests/test_phase41.py -q
....................                                                     [100%]
20 passed in 0.91s

The sibling test fails on the unmodified checkout (it listed secret.txt from proj-private), and passes with the change.

  • python -m pytest tests/ -q passes (no new failures introduced) — ran the containment and Phase 41 suites (20 passed); the full suite needs the optional provider SDKs installed, which this change does not touch
  • ruff check devagent/ tests/ is clean

Notes for reviewers

The grep tool in the same module also takes a path from the model. It shells out to ripgrep with root as its working directory and does not accept a caller-supplied root, so it is not affected by this containment rule — worth a look if you would rather have both tools share one _within_roots()-style helper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

find_files() uses string prefix check for path containment; sibling directories bypass traversal guard

1 participant