diff options
author | Alex Lamar <alawi@vt.edu> | 2016-03-29 23:28:35 -0400 |
---|---|---|
committer | James M Snell <jasnell@gmail.com> | 2016-04-25 09:24:52 -0700 |
commit | de1dc0ae2eb52842b5c5c974090123a64c3a594c (patch) | |
tree | 6b92f1364b21dd093cebffa70a65ee946f06f3ac /lib/module.js | |
parent | 236b7e8dd160be9215cc581b5da1e3ebff67c265 (diff) | |
download | android-node-v8-de1dc0ae2eb52842b5c5c974090123a64c3a594c.tar.gz android-node-v8-de1dc0ae2eb52842b5c5c974090123a64c3a594c.tar.bz2 android-node-v8-de1dc0ae2eb52842b5c5c974090123a64c3a594c.zip |
module: preserve symlinks when requiring
Currently, required modules use the real location of the
package/file as their __filename and __dirname, instead
of the symlinked path if it exists. This behaviour is
undocumented (it even goes against documentation in
certain scenarios), creating hard-to-debug problems
for developers who wish to leverage filesystem abstractions
to lay out their application.
This patch resolves all required modules to their canonical
path while still preserving any symlinks within the path,
instead of resolving to their canonical realpath. The one
special case observed is when the main module is loaded
-- in this case, the realpath does need to be used
in order for the main module to load properly.
PR-URL: https://github.com/nodejs/node/pull/5950
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'lib/module.js')
-rw-r--r-- | lib/module.js | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/lib/module.js b/lib/module.js index f633d62c49..fb233d6c45 100644 --- a/lib/module.js +++ b/lib/module.js @@ -97,27 +97,32 @@ function readPackage(requestPath) { return pkg; } -function tryPackage(requestPath, exts) { +function tryPackage(requestPath, exts, isMain) { var pkg = readPackage(requestPath); if (!pkg) return false; var filename = path.resolve(requestPath, pkg); - return tryFile(filename) || - tryExtensions(filename, exts) || - tryExtensions(path.resolve(filename, 'index'), exts); + return tryFile(filename, isMain) || + tryExtensions(filename, exts, isMain) || + tryExtensions(path.resolve(filename, 'index'), exts, isMain); } // check if the file exists and is not a directory -function tryFile(requestPath) { +// resolve to the absolute realpath if running main module, +// otherwise resolve to absolute while keeping symlinks intact. +function tryFile(requestPath, isMain) { const rc = stat(requestPath); - return rc === 0 && fs.realpathSync(requestPath); + if (isMain) { + return rc === 0 && fs.realpathSync(requestPath); + } + return rc === 0 && path.resolve(requestPath); } // given a path check a the file exists with any of the set extensions -function tryExtensions(p, exts) { +function tryExtensions(p, exts, isMain) { for (var i = 0; i < exts.length; i++) { - const filename = tryFile(p + exts[i]); + const filename = tryFile(p + exts[i], isMain); if (filename) { return filename; @@ -127,7 +132,7 @@ function tryExtensions(p, exts) { } var warned = false; -Module._findPath = function(request, paths) { +Module._findPath = function(request, paths, isMain) { if (path.isAbsolute(request)) { paths = ['']; } else if (!paths || paths.length === 0) { @@ -154,32 +159,36 @@ Module._findPath = function(request, paths) { if (!trailingSlash) { const rc = stat(basePath); if (rc === 0) { // File. - filename = fs.realpathSync(basePath); + if (!isMain) { + filename = path.resolve(basePath); + } else { + filename = fs.realpathSync(basePath); + } } else if (rc === 1) { // Directory. if (exts === undefined) exts = Object.keys(Module._extensions); - filename = tryPackage(basePath, exts); + filename = tryPackage(basePath, exts, isMain); } if (!filename) { // try it with each of the extensions if (exts === undefined) exts = Object.keys(Module._extensions); - filename = tryExtensions(basePath, exts); + filename = tryExtensions(basePath, exts, isMain); } } if (!filename) { if (exts === undefined) exts = Object.keys(Module._extensions); - filename = tryPackage(basePath, exts); + filename = tryPackage(basePath, exts, isMain); } if (!filename) { // try it with each of the extensions at "index" if (exts === undefined) exts = Object.keys(Module._extensions); - filename = tryExtensions(path.resolve(basePath, 'index'), exts); + filename = tryExtensions(path.resolve(basePath, 'index'), exts, isMain); } if (filename) { @@ -374,7 +383,7 @@ Module._load = function(request, parent, isMain) { debug('Module._load REQUEST %s parent: %s', request, parent.id); } - var filename = Module._resolveFilename(request, parent); + var filename = Module._resolveFilename(request, parent, isMain); var cachedModule = Module._cache[filename]; if (cachedModule) { @@ -412,7 +421,7 @@ function tryModuleLoad(module, filename) { } } -Module._resolveFilename = function(request, parent) { +Module._resolveFilename = function(request, parent, isMain) { if (NativeModule.nonInternalExists(request)) { return request; } @@ -424,7 +433,7 @@ Module._resolveFilename = function(request, parent) { // look up the filename first, since that's the cache key. debug('looking for %j in %j', id, paths); - var filename = Module._findPath(request, paths); + var filename = Module._findPath(request, paths, isMain); if (!filename) { var err = new Error("Cannot find module '" + request + "'"); err.code = 'MODULE_NOT_FOUND'; |