Fix handling of paths that leave and re-enter the project root via symlinks #1280
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.
Summary:
Background
The internal implementation of
TreeFS
uses a tree of maps representing file path segments, with a "root" node at the project root. For paths outside the project root, we traverse through'..'
nodes, so that../outside
traverses from the project root through'..'
and'outside'
. Basing the representation around the project root (as opposed to a volume root) minimises traversal through irrelevant paths and makes the cache portable.Problem
However, because this map of maps is a simple (acyclic) tree, a
'..'
node has no entry for one of its logical (=on disk) children - the node closer to the project root. With a project root/foo/bar
, the project-root-relative path../bar
cannot be traversed, because'..'
is a key of'bar'
and not vice-versa.This mostly isn't a problem because
'../bar'
is not a normal path - normalisation collapses this down to''
:metro/packages/metro-file-map/src/lib/RootPathUtils.js
Lines 142 to 148 in 6856d00
Observable bug
For lookups, if instead of a literal indirection we have a symlink
'link-to-parent/bar'
, normalisation cannot (and should not) collapse away the symlink - so after dereferencing the symlink during traversal to'..'
and joining it with the remainingbar
we are unable to lookup'../bar'
. For the module resolver this might appear as a failed existence check, and cause a resolution failure.This fix
When dereferencing a symlink as part of
_lookupByNormalPath
, we now join the symlink target to the remaining subpath using a (mostly pre-exisitng) utility function that is aware of the project root, and can collapse away the project root segments. This leaves a normalised, root-relative target path that's guaranteed not to leave and re-enter the project root.Changelog:
Reviewed By: huntie
Differential Revision: D57719224