Browse Source

Fix #3394 fs.realpath: Properly cache symlink targets

v0.9.1-release
isaacs 13 years ago
parent
commit
131a67e7ef
  1. 16
      lib/fs.js
  2. 34
      test/simple/test-fs-realpath.js

16
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);
}
}

34
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/

Loading…
Cancel
Save