summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2012-06-09 00:33:25 -0700
committerisaacs <i@izs.me>2012-06-09 09:43:47 -0700
commit131a67e7efa2c3010578d9f5fc06ac6f0529af76 (patch)
treee90037cef137092a0de622146c71985e5510f0c2
parent424bca15c8e227a9170cfe00f9ba7d9daae6fb03 (diff)
downloadnode-131a67e7efa2c3010578d9f5fc06ac6f0529af76.tar.gz
Fix #3394 fs.realpath: Properly cache symlink targets
-rw-r--r--lib/fs.js16
-rw-r--r--test/simple/test-fs-realpath.js34
2 files changed, 42 insertions, 8 deletions
diff --git a/lib/fs.js b/lib/fs.js
index f0cd903cb..65df0be35 100644
--- a/lib/fs.js
+++ b/lib/fs.js
@@ -962,21 +962,21 @@ fs.realpathSync = function realpathSync(p, cache) {
// read the link if it wasn't read before
// dev/ino always return 0 on windows, so skip the check.
- var linkTarget;
+ var linkTarget = null;
if (!isWindows) {
var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
- if (seenLinks[id]) {
+ if (seenLinks.hasOwnProperty(id)) {
linkTarget = seenLinks[id];
}
}
- if (!linkTarget) {
+ if (linkTarget === null) {
fs.statSync(base);
linkTarget = fs.readlinkSync(base);
- resolvedLink = pathModule.resolve(previous, linkTarget);
- // track this, if given a cache.
- if (cache) cache[base] = resolvedLink;
- if (!isWindows) seenLinks[id] = linkTarget;
}
+ resolvedLink = pathModule.resolve(previous, linkTarget);
+ // track this, if given a cache.
+ if (cache) cache[base] = resolvedLink;
+ if (!isWindows) seenLinks[id] = linkTarget;
}
// resolve the link, then start over
@@ -1071,7 +1071,7 @@ fs.realpath = function realpath(p, cache, cb) {
// dev/ino always return 0 on windows, so skip the check.
if (!isWindows) {
var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
- if (seenLinks[id]) {
+ if (seenLinks.hasOwnProperty(id)) {
return gotTarget(null, seenLinks[id], base);
}
}
diff --git a/test/simple/test-fs-realpath.js b/test/simple/test-fs-realpath.js
index b2c8e9b01..8741aac69 100644
--- a/test/simple/test-fs-realpath.js
+++ b/test/simple/test-fs-realpath.js
@@ -349,6 +349,40 @@ var uponeActual = fs.realpathSync('..');
assert.equal(upone, uponeActual,
'realpathSync("..") expected: ' + upone + ' actual:' + uponeActual);
+
+// going up with .. multiple times
+// .
+// `-- a/
+// |-- b/
+// | `-- e -> ..
+// `-- d -> ..
+// realpath(a/b/e/d/a/b/e/d/a) ==> a
+function test_up_multiple(cb) {
+ fs.mkdirSync(common.tmpDir + '/a', 0755);
+ fs.mkdirSync(common.tmpDir + '/a/b', 0755);
+ fs.symlinkSync(common.tmpDir + '/a/d', '..');
+ fs.symlinkSync(common.tmpDir + '/a/b/e', '..');
+
+ var abedabed = tmp('abedabed'.split('').join('/'));
+ var abedabeda_real = tmp('');
+
+ var abedabeda = tmp('abedabeda'.split('').join('/'));
+ var abedabeda_real = tmp('a');
+
+ assert.equal(fs.realpathSync(abedabeda), abedabeda_real);
+ assert.equal(fs.realpathSync(abedabed), abedabed_real);
+ fs.realpath(abedabeda, function (er, real) {
+ if (er) throw er;
+ assert.equal(abedabeda_real, real);
+ fs.realpath(abedabed, function (er, real) {
+ if (er) throw er;
+ assert.equal(abedabed_real, real);
+ cb();
+ });
+ });
+}
+
+
// absolute symlinks with children.
// .
// `-- a/