Skip to content

Commit 7dfc196

Browse files
committed
test(search): pin interior-dotdot-after-pin glob edge case
1 parent 131bec7 commit 7dfc196

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

‎src/plugins/search-files-fail-closed.test.ts‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,34 @@ describe("CL-9469 unbounded-root predicate", () => {
334334
);
335335
}
336336
});
337+
// A `..` after the first `**` is never collapsed: hasLiteralBefore only folds
338+
// the prefix *before* the first `**`, so a `..` in unanchored recursive
339+
// descent does not pop the pin. And because rg is cwd-anchored, `a/**/../**`
340+
// descends from `a` and steps back up a relative level — it cannot escape the
341+
// workspace root (there is no `..` above the anchor), so it stays a bounded
342+
// subtree walk of `a`.
343+
test("interior `..` after the pin is a bounded cwd-anchored descent", () => {
344+
for (const pattern of [
345+
"a/**/../**",
346+
"src/**/../**",
347+
"sub/**/../**/*.ts",
348+
"docs/**/../**",
349+
"a/src/**/../**",
350+
"a/**/../src/**",
351+
]) {
352+
expect(isUnboundedRootSearch({ path: undefined, pattern, cwd })).toBe(
353+
false,
354+
);
355+
}
356+
// An all-wildcard pin followed by `..` leaves no name to anchor, so it is
357+
// still an unbounded root walk; a `../../` that folds the prefix to the
358+
// root is refused (already covered as "collapse to the root").
359+
for (const pattern of ["*/**/../**", "a/src/../../**"]) {
360+
expect(isUnboundedRootSearch({ path: undefined, pattern, cwd })).toBe(
361+
true,
362+
);
363+
}
364+
});
337365
test("refusal message carries scope guidance and never reads as a timeout", () => {
338366
const message = formatUnboundedSearchMessage("search_files", "**/*.ts");
339367
expect(message).toContain("narrow `path`");

0 commit comments

Comments
 (0)