Skip to content

fix: absolute in-project paths (#629) + regex alternation false negatives (#628)#630

Open
justrach wants to merge 2 commits into
mainfrom
fix/issues-628-629
Open

fix: absolute in-project paths (#629) + regex alternation false negatives (#628)#630
justrach wants to merge 2 commits into
mainfrom
fix/issues-628-629

Conversation

@justrach

Copy link
Copy Markdown
Owner

Fixes two silent, agent-facing footguns surfaced from real session traces. Both have regression tests; full zig build test is green.

#629codedb_read/codedb_edit reject absolute paths inside the project

isPathSafe rejected every absolute path via a blanket leading-/ check, so a path pointing at a file inside the indexed root returned path traversal not allowed. Agents hold absolute paths, hit the terse error, and abandon codedb for bash — the #626 trajectory shows codedb!,codedb! then seven bash fallbacks.

  • New projectRelPath(path, root): safe relative paths pass through; an absolute path is accepted only when it is exact-or-child of the project root and is rewritten to its relative form.
  • handleRead/handleEdit resolve through it using cwd's realpath as the root.
  • Out-of-root absolutes, .. traversal, NUL bytes, backslashes, and sensitive files stay rejected (the existing issue-93 security test is unchanged).
  • root_policy.isExactOrChild is now pub.

#628 — regex alternation silently returns 0 matches

A top-level alternation like xy|createGateway or .*|foo, where one branch is too short / metachar-only to yield a trigram, prefiltered candidates down to only the trigram-bearing branches — silently dropping files that matched the other branch. mode=regex returned 0 and read as an authoritative "not found".

  • decomposeRegex now detects any branch with zero trigrams and returns an unconstrained query, so the search scans every file.
  • Alternations where every branch has trigrams still prefilter as before.

Tests

  • test_mcp.zigissue-629: projectRelPath accepts absolute paths inside the project root
  • test_index.zigissue-628: alternation with a no-trigram branch falls back to scan-all (verified to fail pre-fix with expected 0, found 1)

Closes #629
Closes #628

🤖 Generated with Claude Code

justrach and others added 2 commits June 19, 2026 11:37
isPathSafe rejected every absolute path with a blanket leading-`/`
check, so codedb_read / codedb_edit returned "path traversal not
allowed" for a file that lives *inside* the indexed project. Agents
hold absolute paths, hit the terse error, and abandon codedb for bash
(the #626 trajectory shows codedb!,codedb! then seven bash calls).

Add projectRelPath(path, root): a safe relative path passes through;
an absolute path is accepted only when it is exact-or-child of the
project root and is rewritten to its relative form; out-of-root
absolutes, `..` traversal, nulls and backslashes stay rejected.
handleRead/handleEdit resolve the path through it using cwd's realpath
as the root. isExactOrChild is now pub for reuse.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
In `mode=regex`, a top-level alternation like `xy|createGateway` (or
`.*|foo`) where one branch yields no trigrams was prefiltered down to
only the trigram-bearing branches' candidate files. Files matching the
no-trigram branch were silently dropped, so the search returned 0
matches and read as an authoritative "not found".

decomposeRegex now detects any branch that produces zero trigrams and
returns an unconstrained query, so candidatesRegex returns null and the
search scans every file. Alternations where every branch has trigrams
still prefilter as before.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

👋 Thanks for the contribution! Quick heads-up: this repo lands changes on the current release/* branch, not main.

Please retarget this PR via Edit → base branch to the active release branch (currently release/0.2.5825).

(Automated hint — reply here if you need a hand.)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 31233f95ff

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/mcp.zig
Comment on lines +2807 to +2808
const root: []const u8 = if (std.Io.Dir.cwd().realPathFile(io, ".", &root_buf)) |n| root_buf[0..n] else |_| "";
const path = projectRelPath(path_arg, root) orelse {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use the indexed project root for absolute read paths

When codedb /some/project mcp is launched from a different working directory (or deferred roots select a workspace different from the launch cwd), this normalizes absolute paths against the process cwd rather than the indexed root (explorer.root_path). An absolute path under the launch cwd but outside the project is therefore accepted and rewritten to a relative path; if that path is not cached in the project index, handleRead falls through to cwd().readFileAlloc and returns an out-of-scope file. It also still rejects absolute paths inside the actual indexed project in that launch mode, so the #629 fix only works when cwd equals the project root.

Useful? React with 👍 / 👎.

@github-actions

Copy link
Copy Markdown

Benchmark Regression Report

Thresholds: 10.00% and 50,000 ns absolute delta

NOISE means the percentage threshold was exceeded, but the absolute delta was too small to fail CI.

Tool Base (ns) Head (ns) Delta Abs Delta (ns) Status
codedb_bundle 102497 102869 +0.36% +372 OK
codedb_changes 10175 13809 +35.71% +3634 NOISE
codedb_context 793602 857538 +8.06% +63936 OK
codedb_deps 318 314 -1.26% -4 OK
codedb_edit 40158 41672 +3.77% +1514 OK
codedb_find 2857 2738 -4.17% -119 OK
codedb_hot 24820 27879 +12.32% +3059 NOISE
codedb_outline 37683 38125 +1.17% +442 OK
codedb_read 15912 24467 +53.76% +8555 NOISE
codedb_search 13152 14258 +8.41% +1106 OK
codedb_snapshot 69900 73261 +4.81% +3361 OK
codedb_status 9338 8594 -7.97% -744 OK
codedb_symbol 52140 54612 +4.74% +2472 OK
codedb_tree 19449 24154 +24.19% +4705 NOISE
codedb_word 11899 13613 +14.40% +1714 NOISE

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

Labels

None yet

Projects

None yet

1 participant