Files
510dd07d6b v1.92.9.0 fix: /freeze checks where an edit really lands, so new-folder paths can't escape it (#3623) (#3758)
* fix(freeze): resolve the full path before the boundary check, fail closed when it can't (#3623)

check-freeze.sh canonicalized only an existing parent directory and compared
the raw string otherwise, so any path through a directory that did not exist
yet kept its literal in-boundary prefix: '<b>/../outside/new/x',
'<b>/link-out/new/x', '<b>/..', '~/.zshrc' with cwd inside, and
'C:\proj\src\..\..\other\new\x' were all allowed.

_resolve_path now walks the path one component at a time, follows symlinks at
any depth, and requires both the OS reading and a lexical normalizer's reading
of '..' to land inside. Paths it cannot place deny with a reason: symlink
loops and chains over 40 links, line breaks, Windows drive- and root-relative
paths, names Windows trims, odd UNC roots. Windows rules keep '..' at the drive
or share root. The shared extractor keeps trailing newlines and maps lone
surrogates on path fields only; /careful's command values are unchanged.

Co-authored-by: Quinn O'Donnell <90010678+Quinnod345@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(freeze): deny paths over PATH_MAX before the quadratic walk (#3623)

A PreToolUse hook that outlives the host's timeout does not block the edit,
and the component walk is quadratic in path length. Deny a file_path over
4096 characters, and links that grow the walk past 8192, before walking.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(freeze): bound the total length of followed link targets (#3623)

The PATH_MAX cap bounded only the file_path text; each link hop could add
up to 8192 characters again, and a padded 40-link chain kept the quadratic
walk busy for 104s. Count every target against one 8192-character budget.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* test(freeze): cheap link-chain budget test; name the path in the budget reason (#3623)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs(changelog): /freeze boundary escape fix (#3623)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs(freeze): describe full-path resolution and fail-closed cases (#3623)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* freeze: deny Windows link targets relative to a drive or its root (#3623)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* freeze: read a leading // as / on POSIX hosts, never as a UNC prefix (#3623)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* freeze: compare Git Bash paths by cygpath's drive spelling (#3623)

Git Bash mounts %TEMP% at /tmp and converts HOME through its mounts, so
'~/x' and 'D:\...\x' named one file in two spellings and the hook denied
a legit edit (windows-free-shard 2 on #3758).

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* freeze: name the edited path as given in the deny, with where it lands (#3623)

cygpath's drive spelling made a Windows deny print /c/Program Files/Git/etc/hosts
for /etc/hosts (windows-free-shard 2 on #3758, 'Edit denials name the tool and
file_path too').

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: Quinn O'Donnell <90010678+Quinnod345@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-11-01 02:06:25 +00:00
..