summaryrefslogtreecommitdiff
path: root/lib/module.js
diff options
context:
space:
mode:
authorAlex Lamar <alawi@vt.edu>2016-03-29 23:28:35 -0400
committerJames M Snell <jasnell@gmail.com>2016-04-25 09:24:52 -0700
commitde1dc0ae2eb52842b5c5c974090123a64c3a594c (patch)
tree6b92f1364b21dd093cebffa70a65ee946f06f3ac /lib/module.js
parent236b7e8dd160be9215cc581b5da1e3ebff67c265 (diff)
downloadandroid-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.js43
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';