Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Gracefully handle symlinks to ., .., etc in
require.context
Summary: `matchFilesWithContext` powers `require.context`, returning all paths under a given root matching a given `regex`. This is originally an established [Webpack feature](https://webpack.js.org/guides/dependency-management/#requirecontext), and we aim to match behaviour as closely as we can. Webpack *does* follow symlinks when enumerating paths prior to matching, so that for example in the following file layout: ``` - link-to-foo -> foo - foo - - bar.js ``` `link-to-foo/bar.js` is enumerated, so that `require.context(myRoot, true, /link-to-foo\/bar.js/)` matches. Webpack's implementation of this uses recursive `fs.readdir` calls, following symlinks, to enumerate all reachable paths. This raises the question of handling a kind of cycle, for example: ``` - foo -> . - bar.js ``` Would theoretically match `./bar.js`, `./foo/bar.js`, `./foo/foo/bar.js` and so on. Webpack actually dies on this, throwing `ELOOP` from `fs`. Similarly, currently, Metro will crash with call stack size exceeded inside `_pathIterator`. This diff makes the (arguably arbitrary, but reasonablish) choice to follow symlinks at most once per path, by tracking "seen" links in a set during enumeration. ``` - foo -> . - baz -> . - bar.js ``` Expands to: ``` bar.js foo/bar.js foo/baz/bar.js baz/bar.js baz/foo/bar.js ``` Changelog: ``` - **[Experimental]**: Fix crash when `require.context` is used on a directory with infinite path expansions. Reviewed By: motiz88 Differential Revision: D46767544 fbshipit-source-id: ed3d17b3afcf27189aa442627a31b6225fd873bf
- Loading branch information