Skip to content

Commit c83368a

Browse files
committed
fix(path): normalize traversal segments in resolvePathFromCwd
The unification commit (1535672) replaced init.ts's resolveDestinationPath wrapper, which did `path.resolve(expandHomePrefix(input))`. The shared helper kept absolute inputs verbatim, dropping the implicit normalization step that path.resolve() with one argument provides. That regressed init.ts's filesystem-root guard (`resolvedDest === path.parse(resolvedDest).root`), which only matches exact-root strings. Inputs like `--dest /foo/..` or `--dest /..` resolved to themselves, bypassing the guard, even though the kernel-level path collapses to `/`. Restore normalization at the helper layer by delegating unconditionally to `path.resolve(cwd, expanded)`. `path.resolve(cwd, X)` already produces the correct result for both absolute and relative `X`, and always normalizes, so the absolute/relative branch is redundant. The four other migrated call sites (build-utils, app-path-resolver, derived-data-path, project-config) gain a benign normalization improvement; only init.ts's guards depended on it for correctness. Tests added cover `/foo/..` -> `/` and `/a/b/../c` -> `/a/c`.
1 parent 1535672 commit c83368a

2 files changed

Lines changed: 12 additions & 7 deletions

File tree

src/utils/__tests__/path.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,12 @@ describe('resolvePathFromCwd', () => {
6767
it('does not expand ~user style prefixes', () => {
6868
expect(resolvePathFromCwd('~other/foo')).toBe(path.resolve(process.cwd(), '~other/foo'));
6969
});
70+
71+
it('normalizes traversal segments in absolute paths', () => {
72+
expect(resolvePathFromCwd('/foo/..')).toBe('/');
73+
});
74+
75+
it('normalizes interior traversal segments in absolute paths', () => {
76+
expect(resolvePathFromCwd('/a/b/../c')).toBe('/a/c');
77+
});
7078
});

src/utils/path.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,10 @@ export function expandHomePrefix(inputPath: string): string {
1818
}
1919

2020
/**
21-
* Resolve a user-supplied path: expand ~ then return as-is when absolute,
22-
* otherwise resolve against `cwd` (defaults to process.cwd()).
21+
* Resolve a user-supplied path: expand ~ then resolve against `cwd`
22+
* (defaults to process.cwd()). Always returns a normalized absolute path —
23+
* traversal segments like `/foo/..` collapse to `/`.
2324
*/
2425
export function resolvePathFromCwd(pathValue: string, cwd: string = process.cwd()): string {
25-
const expanded = expandHomePrefix(pathValue);
26-
if (path.isAbsolute(expanded)) {
27-
return expanded;
28-
}
29-
return path.resolve(cwd, expanded);
26+
return path.resolve(cwd, expandHomePrefix(pathValue));
3027
}

0 commit comments

Comments
 (0)