Skip to content

normalizePath roots a relative path beginning with ./ followed by a slash #63588

Description

🔎 Search Terms

normalizePath, getNormalizedAbsolutePath, simpleNormalizePath, leading ./, relative path rooted

🕗 Version & Regression Information

Regression introduced by #60812 ("Write path normalization without array allocations"), which added the simpleNormalizePath fast path.

⏯ Playground / Reproduction

normalizePath and getNormalizedAbsolutePath turn a relative path that begins with ./ followed by a redundant separator into a rooted path:

import { normalizePath, getNormalizedAbsolutePath } from "typescript";

normalizePath(".//a");                       // "/a"    — expected "a"
normalizePath("././/a");                     // "/a"    — expected "a"
getNormalizedAbsolutePath(".//a/b", "");     // "/a/b"  — expected "a/b"

🙁 Actual behavior

simpleNormalizePath runs path.replace(/\/\.\//g, "/") (a no-op for .//a) and then if (simplified.startsWith("./")) simplified = simplified.slice(2). For .//a that strips ./ and leaves /a — but the second / was a redundant separator, not a root — so the result is returned as a rooted path. A relative path is silently converted to an absolute one. The slow-path component walker returns the correct relative result.

🙂 Expected behavior

.//aa, .//a/ba/b, ././/aa (stay relative), matching the slow path.

Additional information

Proposed fix in #63587: only strip the leading ./ when the next character is not another separator (otherwise fall through to the slow path). Verified on the bundled compiler with an exhaustive differential over all strings up to length 8 from {'.', '/', 'a'} (9,840 inputs): 172 results change, every one a ./-then-separator case corrected to match the slow path; zero changes elsewhere.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions