diff options
author | Rongjian Zhang <pd4d10@gmail.com> | 2019-11-22 14:01:21 +0800 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2019-12-03 23:48:08 +0100 |
commit | 0e3d774ed21375675b024f555a67773821e56a9d (patch) | |
tree | 40b8710c72e8adab75dbae5632c81a76f715667c | |
parent | 3ebae6cf1b20ce104423214d75c3c84129a8f141 (diff) | |
download | android-node-v8-0e3d774ed21375675b024f555a67773821e56a9d.tar.gz android-node-v8-0e3d774ed21375675b024f555a67773821e56a9d.tar.bz2 android-node-v8-0e3d774ed21375675b024f555a67773821e56a9d.zip |
fs: fix existsSync for invalid symlink at win32
Fixes: https://github.com/nodejs/node/issues/30538
PR-URL: https://github.com/nodejs/node/pull/30556
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
-rw-r--r-- | lib/fs.js | 11 | ||||
-rw-r--r-- | test/parallel/test-fs-symlink-dir-junction.js | 17 | ||||
-rw-r--r-- | test/parallel/test-fs-symlink-dir.js | 22 | ||||
-rw-r--r-- | test/parallel/test-fs-symlink.js | 12 |
4 files changed, 61 insertions, 1 deletions
@@ -234,7 +234,16 @@ function existsSync(path) { return false; } const ctx = { path }; - binding.access(pathModule.toNamespacedPath(path), F_OK, undefined, ctx); + const nPath = pathModule.toNamespacedPath(path); + binding.access(nPath, F_OK, undefined, ctx); + + // In case of an invalid symlink, `binding.access()` on win32 + // will **not** return an error and is therefore not enough. + // Double check with `binding.stat()`. + if (isWindows && ctx.errno === undefined) { + binding.stat(nPath, false, undefined, ctx); + } + return ctx.errno === undefined; } diff --git a/test/parallel/test-fs-symlink-dir-junction.js b/test/parallel/test-fs-symlink-dir-junction.js index fc89ad3684..42d6bc1214 100644 --- a/test/parallel/test-fs-symlink-dir-junction.js +++ b/test/parallel/test-fs-symlink-dir-junction.js @@ -53,3 +53,20 @@ fs.symlink(linkData, linkPath, 'junction', common.mustCall(function(err) { })); })); })); + +// Test invalid symlink +{ + const linkData = fixtures.path('/not/exists/dir'); + const linkPath = path.join(tmpdir.path, 'invalid_junction_link'); + + fs.symlink(linkData, linkPath, 'junction', common.mustCall(function(err) { + assert.ifError(err); + + assert(!fs.existsSync(linkPath)); + + fs.unlink(linkPath, common.mustCall(function(err) { + assert.ifError(err); + assert(!fs.existsSync(linkPath)); + })); + })); +} diff --git a/test/parallel/test-fs-symlink-dir.js b/test/parallel/test-fs-symlink-dir.js index 1ab1361a43..707bc5b486 100644 --- a/test/parallel/test-fs-symlink-dir.js +++ b/test/parallel/test-fs-symlink-dir.js @@ -44,3 +44,25 @@ for (const linkTarget of linkTargets) { testAsync(linkTarget, `${linkPath}-${path.basename(linkTarget)}-async`); } } + +// Test invalid symlink +{ + function testSync(target, path) { + fs.symlinkSync(target, path); + assert(!fs.existsSync(path)); + } + + function testAsync(target, path) { + fs.symlink(target, path, common.mustCall((err) => { + assert.ifError(err); + assert(!fs.existsSync(path)); + })); + } + + for (const linkTarget of linkTargets.map((p) => p + '-broken')) { + for (const linkPath of linkPaths) { + testSync(linkTarget, `${linkPath}-${path.basename(linkTarget)}-sync`); + testAsync(linkTarget, `${linkPath}-${path.basename(linkTarget)}-async`); + } + } +} diff --git a/test/parallel/test-fs-symlink.js b/test/parallel/test-fs-symlink.js index a600110319..c52ffbc105 100644 --- a/test/parallel/test-fs-symlink.js +++ b/test/parallel/test-fs-symlink.js @@ -58,6 +58,18 @@ fs.symlink(linkData, linkPath, common.mustCall(function(err) { })); })); +// Test invalid symlink +{ + const linkData = fixtures.path('/not/exists/file'); + const linkPath = path.join(tmpdir.path, 'symlink2.js'); + + fs.symlink(linkData, linkPath, common.mustCall(function(err) { + assert.ifError(err); + + assert(!fs.existsSync(linkPath)); + })); +} + [false, 1, {}, [], null, undefined].forEach((input) => { const errObj = { code: 'ERR_INVALID_ARG_TYPE', |