Skip to content

fix(metro-file-map): Fix Windows cross-device path resolution#1711

Closed
kitten wants to merge 10 commits into
react:mainfrom
kitten:@kitten/fix/metro-file-map-windows-cross-device-paths
Closed

fix(metro-file-map): Fix Windows cross-device path resolution#1711
kitten wants to merge 10 commits into
react:mainfrom
kitten:@kitten/fix/metro-file-map-windows-cross-device-paths

Conversation

@kitten

@kitten kitten commented May 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Related PR for expo/expo fork: expo/expo#45648
Supersedes #1696

Cross-device path normals are intended to be relative paths from the rootDir. If the rootDir is at C:\project then a cross-device normal path at D:\temp is represented as ..\..\D:\temp. This assumption is broken in several places, like normalToAbsolute printing, leading to C:\D:\ paths that are invalid.

Changelog: [Fix] Fix Windows path handling for cross-drive paths

Test plan

  • Unit tests were adjusted to demonstrate all failing cases
  • Note: Invalid unit tests have been removed for paths that rise above the filesystem root (they're assumed to be impossible, and their output doesn't have to be deterministic/correct)

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label May 11, 2026
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label May 11, 2026
kitten added a commit to expo/expo that referenced this pull request May 11, 2026
# Why

Reported at react/metro#1696. This PR is
being upstreamed at: react/metro#1711

The intention in Metro is that cross-device paths are represented as
relative normal paths. If the root dir is at `C:\project` then a
cross-device normal path at `D:\temp` is represented as `..\..\D:\temp`.
This assumption is broken in several places, like `normalToAbsolute`
printing, leading to `C:\D:\` paths that are invalid.

# How

- Fix `normalToAbsolute` not cutting off cross-device absolute paths
- Fix `resolveSymlinkToNormal` cutting off trailing slash for absolute
Windows device paths
- Prevent double slash when appending normal path to root `C:\` path
- Prevent `TreeFS#remove` from re-normalizing internally built paths,
which can lead to excessively clamped paths
- Adjust relative root maximum depth for Windows (remove `-1` adjustment
for Windows)

# Test Plan

- Represented in unit test changes
- **Note:** Invalid unit tests have been removed for paths that rise
above the filesystem root

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [x] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
@meta-codesync

meta-codesync Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor

@CalixTang has imported this pull request. If you are a Meta employee, you can view this in D104700077.

@robhogan

Copy link
Copy Markdown
Contributor

Thanks again for looking at this!

Invalid unit tests have been removed for paths that rise above the filesystem root (they're assumed to be impossible, and their output doesn't have to be deterministic/correct)

This is very edge-casey but the behaviour of .. at the root is actually specified (at least on posix), those test cases weren't invalid or accidental.

https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13

The special filename dot shall refer to the directory specified by its predecessor. The special filename dot-dot shall refer to the parent directory of its predecessor directory. As a special case, in the root directory, dot-dot may refer to the root directory itself.

In particular, if you create a symlink with the target ../../../../file-at-root.txt at /, it will deference to /file-at-root.txt on posix, so it should with Metro as well.

@robhogan

Copy link
Copy Markdown
Contributor

(Also, nit: device != drive. These are cross-drive paths)

@kitten

kitten commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

interesting! that's an easy fix, but requires us to use startsWithDriveLetter (as per expo/expo#45648) in one place, I believe, so it's a bit of a trade-off. I didn't measure performance in that case, but I think it might not be otherwise possible to differentiate between the Windows/Posix root case otherwise. Although, I could be mistaken and there could be an easier way, if we ignore this case for Windows.

Comment thread packages/metro-file-map/src/lib/TreeFS.js Outdated
Comment thread packages/metro-file-map/src/lib/RootPathUtils.js
Co-authored-by: Rob Hogan <2590098+robhogan@users.noreply.github.com>
@kitten kitten force-pushed the @kitten/fix/metro-file-map-windows-cross-device-paths branch from ab79459 to 9884f2a Compare May 12, 2026 15:27
@meta-codesync

meta-codesync Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor

@CalixTang merged this pull request in 6e6b52c.

kitten added a commit to expo/expo that referenced this pull request May 13, 2026
…-up) (#45687)

# Why

Follow-up to #45648 to address review feedback at
react/metro#1711 (ongoing)

# How

- Fix `'..'` at root handling to align with Metro

# Test Plan

- Covered by unit test changes

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [x] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants