Resolve both operands in isUnderRoot so containment works on Windows - #807
Open
anketpratapsingh wants to merge 1 commit into
Open
Resolve both operands in isUnderRoot so containment works on Windows#807anketpratapsingh wants to merge 1 commit into
anketpratapsingh wants to merge 1 commit into
Conversation
isUnderRoot() applied path.resolve() to filePath but only path.normalize() to repoRoot. On Windows resolve() prepends the current drive letter and normalize() does not, so a genuinely contained file compared "C:\repo\src\a.ts" against "\repo" and was rejected. The function is duplicated verbatim in travsr-lsif-ts and travsr-lsif-py; both copies are fixed. Not exploitable in the current call path (walker.ts always passes a root from resolveRoot(), which is already absolute), but the red test made npm test unrunnable on Windows dev machines, and the containment filter's correctness silently depended on an unstated caller precondition. It now holds for any input, and the doc comment records why. The function takes an optional pathImpl parameter (defaulting to the host path module) so the tests can pin its Windows AND POSIX behaviour from any host: new tests inject path.win32 and path.posix explicitly with fully-qualified inputs, making the platform matrix part of every test run instead of only surfacing on whichever OS CI happens to use. Production callers never pass it. Fixes #806
Benchmark comparison (master → PR)Threshold: p95 regression ≥ +10% fails this check. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #806.
isUnderRoot()appliedpath.resolve()tofilePathbut onlypath.normalize()torepoRoot. On Windowsresolve()prepends the current drive letter andnormalize()does not, so a genuinely contained file comparedC:\repo\src\a.tsagainst\repoand was rejected — turning the containment check red on Windows (npm testexited 1 with 25/26 passing).The function is duplicated verbatim in both packages; both copies are fixed:
packages/travsr-lsif-ts/src/security.tspackages/travsr-lsif-py/src/security.tsPer the issue: not exploitable in the current call path (
walker.tsalways passes a root fromresolveRoot(), which is already absolute), but the filter's correctness silently depended on that unstated caller precondition, and it fails in the direction of dropping legitimate files. It now holds for any input, and the doc comment records why.Cross-platform testing
The fix must hold on Windows, macOS, and Linux. Rather than leaving each platform's behaviour to whichever OS happens to run the suite, the function now takes an optional
pathImpl: typeof path = pathparameter (production callers never pass it), and new tests injectpath.win32andpath.posixexplicitly with fully-qualified inputs — so every test run on any host exercises both platforms' semantics deterministically:isUnderRoot: Windows semantics, verified from any host (#806)— drive-letter containment, forward-slash normalization, prefix-escape (project-evil), other-drive rejection,..traversal collapseisUnderRoot: POSIX semantics, verified from any host (#806)— containment, prefix-escape,..traversal collapsetravsr-lsif-tsnpm run build+npm test→ 28/28 pass, exit 0 (was 25/26, exit 1).travsr-lsif-py:tscbuild clean + 11 assertions against the real compileddist/security.js(nativetree-sitterinstall needs Python/node-gyp, unavailable on this machine, so the full py suite ran as a direct-import harness instead)lsif-tsjob onubuntu-latestruns the full suite including the new injected-flavour testsisUnderRootdoes zero I/O — it is pure string manipulation over thepathmodule, and Node'spathon macOS is byte-for-byte the same POSIX implementation as on Linux (path.posix). That exact flavour is pinned by the injected-path.posixtest, which runs on every host, including the Linux CI run of this PRNotes for reviewers
travsr-lsif-pyhas no CI job (onlylsif-tsis wired intoci.yml), so its copy of this fix is not exercised by CI at all — flagging in case alsif-pyjob is worth adding while this is fresh.security.tsfiles had already drifted slightly around this function; the issue suggests a shared module as a follow-up, deliberately not done here to keep the fix minimal.