You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Avoid climbing across Windows drives when rebasing URLs in stylesheets - #20683
When an entry stylesheet and an imported stylesheet are located on different Windows drive letters (or different UNC shares), path.posix.relative treats drive letters as regular directory names. This causes rebaseUrl to emit a drive-climbing path like url("../../../../../../../H:/.../images/probe.svg") when trying to relate paths across drives.
In this PR:
Detect when root and base have different roots (such as different Windows drive letters or UNC shares) using path.win32.parse(). When they are on different drives, there is no valid relative path between them, so rebaseUrl preserves the resolved absolute URL.
Normalize drive letter casing so same-drive comparisons (e.g. c: vs C:) continue to rebase relatively without generating ../ prefixes.
Return already-absolute Windows paths early, matching the existing behavior for / root paths.
Test plan
Added unit tests in packages/@tailwindcss-node/src/urls.test.ts:
Tested cross-drive URL rewriting (C: root with H: base) to verify the absolute URL is retained.
Tested same-drive URL rewriting with differing drive letter casing (c: vs C:) to ensure relative rebasing is preserved.
Tested parent directory navigation (../) on cross-drive stylesheets to ensure resolution keeps the correct path.
Tested already-absolute Windows drive paths in url() to verify they are preserved.
Ran vitest across @tailwindcss-node:
All 12 tests in @tailwindcss-node passed.
It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.
No actionable comments were generated in the recent review.
Walkthrough
The URL rebasing logic now recognizes Windows-absolute URLs and compares normalized Windows roots. When the roots differ, it returns the joined absolute path. When the roots match, it computes a relative URL. Path normalization now recognizes network-share paths with either slash form. Tests cover cross-drive paths, drive-letter case differences, parent-directory references, absolute drive URLs, UNC paths, and escaped spaces.
Severity of issue fixed: Medium
Merge Risk: Minimal · up to 45bbd
The previously reported UNC rebasing risk is addressed. No actionable risk introduced by this PR remains after normal checks.
Pre-merge checks: 4
Check name
Status
Explanation
Title check
The title names the main change: rebasing URLs in stylesheets no longer climbs across Windows drives. It matches the changeset, which detects differing drive roots and UNC shares in rebaseUrl and pres…
Description check
The description states the problem (cross-drive relative paths producing drive-climbing URLs), the fix (differing-root detection, drive-letter casing normalization, early return for absolute Windows p…
Linked Issues check
[#20682] requires that cross-drive stylesheet rebasing avoid drive-climbing relative paths. The issue accepts either the retained absolute URL or a path that keeps the drive.
Code at head (whole-PR d…
Out of Scope Changes check
The whole-PR diff changes three files, and each connects to [#20682]. - urls.ts: changes rebaseUrl and adds getPathRoot, normalizeRootVolume, and joinWithBase for cross-drive and UNC roots. …
Full details: Title check
Explanation
The title names the main change: rebasing URLs in stylesheets no longer climbs across Windows drives. It matches the changeset, which detects differing drive roots and UNC shares in rebaseUrl and preserves the absolute URL. The title is concise and specific.
Full details: Description check
Explanation
The description states the problem (cross-drive relative paths producing drive-climbing URLs), the fix (differing-root detection, drive-letter casing normalization, early return for absolute Windows paths), and the tests added in urls.test.ts. It relates directly to the changeset.
Full details: Linked Issues check
Explanation
[#20682] requires that cross-drive stylesheet rebasing avoid drive-climbing relative paths. The issue accepts either the retained absolute URL or a path that keeps the drive.
Code at head (whole-PR diff, merge base 9b2c925 to head 45bbd8d):
rebaseUrl in packages/@tailwindcss-node/src/urls.ts computes getPathRoot for root and base with path.win32.parse. When the roots differ, it returns the joined absolute URL and skips path.posix.relative. This resolves the cross-drive case (for example C: root and H: base).
Same-drive inputs still reach path.posix.relative, so output stays relative.
normalizeRootVolume uppercases drive letters, so c: and C: compare equal.
Already-absolute Windows URLs return early through path.win32.isAbsolute(url).
UNC roots compare by lowercased server and share prefix. normalize-path.ts now also treats // prefixes as network-share paths.
Tests at head in urls.test.ts cover: cross-drive output (H:/tw-repro/app/images/probe.svg), parent navigation across drives, c: versus C: same-drive rebasing, already-absolute drive URLs, cross-share and same-share UNC cases, and drive-to-drive parent traversal.
The tests were not executed in this assessment. The 12-test pass result is author-reported. The test expectations match the code paths above on source reading.
Full details: Out of Scope Changes check
Explanation
The whole-PR diff changes three files, and each connects to [#20682].
urls.ts: changes rebaseUrl and adds getPathRoot, normalizeRootVolume, and joinWithBase for cross-drive and UNC roots. This is the issue scope.
urls.test.ts: adds regression tests for the new branches. This is supporting test coverage.
normalize-path.ts: extends the existing UNC prefix check from \\ to also cover //. The UNC tests in urls.test.ts exercise this path, so the change supports the issue scope.
The test CSS escape backslashes in URLs are preserved on Windows paths guards the new same-drive path against changing backslash escapes. It adds no unrelated behavior. No unrelated feature or file change appears in the diff.
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
File: No configuration file from this repository applied
Commit: Unavailable
Layers: Repository UI
Review profile: CHILL
Plan: Advanced
Run ID: 2b9e2eda-068f-418e-b066-95d0e0d67874
Commits
Reviewing files that changed from the base of the PR and between dc49eee and 45bbd8d.
Files selected for processing: 2
packages/@tailwindcss-node/src/urls.test.ts
packages/@tailwindcss-node/src/urls.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Review info
Run configuration
Source mode: Auto
Repository: Unavailable
Branch: Unavailable
File: No configuration file from this repository applied
Commit: Unavailable
Layers: Repository UI
Review profile: CHILL
Plan: Advanced
Run ID: 3fe4b216-9f94-4300-8867-b5c3b51b725e
Commits
Reviewing files that changed from the base of the PR and between 9b2c925 and 5fb28a6.
Files selected for processing: 2
packages/@tailwindcss-node/src/urls.test.ts
packages/@tailwindcss-node/src/urls.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.
The reason will be displayed to describe this comment to others. Learn more.
Caution
Some comments are outside the diff and can’t be posted inline due to GitHub limitations.
⚠️ Outside diff range comments (1)
Major · Calculate same-share UNC paths without case-sensitive root segments. · urls.ts:130
packages/@tailwindcss-node/src/urls.ts:130 Major · Functional Correctness · Quick win
Calculate same-share UNC paths without case-sensitive root segments.
If root is //server/share/app and base is //SERVER/SHARE/app/styles, getPathRoot treats them as the same share. path.posix.relative still treats the differently cased share segments as different directories. It emits a path such as ../../../SERVER/SHARE/app/styles/images/probe.svg, which does not point to the asset when resolved from the UNC share. Use a case-insensitive Windows relative-path calculation for same-share UNC paths, then convert its separators for CSS. (raw.githubusercontent.com)
Review info
Run configuration
Source mode: Auto
Repository: Unavailable
Branch: Unavailable
File: No configuration file from this repository applied
Commit: Unavailable
Layers: Repository UI
Review profile: CHILL
Plan: Advanced
Run ID: b4b29233-08bf-4b12-989d-202c4eb10caa
Commits
Reviewing files that changed from the base of the PR and between 5fb28a6 and 130f517.
Files selected for processing: 3
packages/@tailwindcss-node/src/normalize-path.ts
packages/@tailwindcss-node/src/urls.test.ts
packages/@tailwindcss-node/src/urls.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.
When
oot and �ase reside on the same Windows drive or UNC share, we now use path.win32.relative(normalizedRoot, absoluteUrl).replaceAll('\', '/') to perform case-insensitive relative path resolution. This prevents differently-cased root/share segments (e.g. //server/share vs //SERVER/SHARE) from producing extraneous climbing paths.
Added regression test same-share UNC paths with differing casing rebase relatively without duplicate segments in packages/@tailwindcss-node/src/urls.test.ts.
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Review info
Run configuration
Source mode: Auto
Repository: Unavailable
Branch: Unavailable
File: No configuration file from this repository applied
Commit: Unavailable
Layers: Repository UI
Review profile: CHILL
Plan: Advanced
Run ID: 4a23de96-b1d7-4775-9477-d0b8d86d6d6a
Commits
Reviewing files that changed from the base of the PR and between 130f517 and 4ab2521.
Files selected for processing: 2
packages/@tailwindcss-node/src/urls.test.ts
packages/@tailwindcss-node/src/urls.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.
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
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.
Fixes #20682.
Summary
When an entry stylesheet and an imported stylesheet are located on different Windows drive letters (or different UNC shares),
path.posix.relativetreats drive letters as regular directory names. This causesrebaseUrlto emit a drive-climbing path likeurl("../../../../../../../H:/.../images/probe.svg")when trying to relate paths across drives.In this PR:
rootandbasehave different roots (such as different Windows drive letters or UNC shares) usingpath.win32.parse(). When they are on different drives, there is no valid relative path between them, sorebaseUrlpreserves the resolved absolute URL.c:vsC:) continue to rebase relatively without generating../prefixes./root paths.Test plan
Added unit tests in
packages/@tailwindcss-node/src/urls.test.ts:C:root withH:base) to verify the absolute URL is retained.c:vsC:) to ensure relative rebasing is preserved.../) on cross-drive stylesheets to ensure resolution keeps the correct path.url()to verify they are preserved.Ran vitest across
@tailwindcss-node:All 12 tests in
@tailwindcss-nodepassed.