Skip to content

Commit 60b1e1a

Browse files
pd4d10targos
authored andcommitted
fs: fix existsSync for invalid symlink at win32
Fixes: #30538 PR-URL: #30556 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 71d43a5 commit 60b1e1a

File tree

4 files changed

+61
-1
lines changed

4 files changed

+61
-1
lines changed

lib/fs.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,16 @@ function existsSync(path) {
234234
return false;
235235
}
236236
const ctx = { path };
237-
binding.access(pathModule.toNamespacedPath(path), F_OK, undefined, ctx);
237+
const nPath = pathModule.toNamespacedPath(path);
238+
binding.access(nPath, F_OK, undefined, ctx);
239+
240+
// In case of an invalid symlink, `binding.access()` on win32
241+
// will **not** return an error and is therefore not enough.
242+
// Double check with `binding.stat()`.
243+
if (isWindows && ctx.errno === undefined) {
244+
binding.stat(nPath, false, undefined, ctx);
245+
}
246+
238247
return ctx.errno === undefined;
239248
}
240249

test/parallel/test-fs-symlink-dir-junction.js

+17
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,20 @@ fs.symlink(linkData, linkPath, 'junction', common.mustCall(function(err) {
5353
}));
5454
}));
5555
}));
56+
57+
// Test invalid symlink
58+
{
59+
const linkData = fixtures.path('/not/exists/dir');
60+
const linkPath = path.join(tmpdir.path, 'invalid_junction_link');
61+
62+
fs.symlink(linkData, linkPath, 'junction', common.mustCall(function(err) {
63+
assert.ifError(err);
64+
65+
assert(!fs.existsSync(linkPath));
66+
67+
fs.unlink(linkPath, common.mustCall(function(err) {
68+
assert.ifError(err);
69+
assert(!fs.existsSync(linkPath));
70+
}));
71+
}));
72+
}

test/parallel/test-fs-symlink-dir.js

+22
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,25 @@ for (const linkTarget of linkTargets) {
4444
testAsync(linkTarget, `${linkPath}-${path.basename(linkTarget)}-async`);
4545
}
4646
}
47+
48+
// Test invalid symlink
49+
{
50+
function testSync(target, path) {
51+
fs.symlinkSync(target, path);
52+
assert(!fs.existsSync(path));
53+
}
54+
55+
function testAsync(target, path) {
56+
fs.symlink(target, path, common.mustCall((err) => {
57+
assert.ifError(err);
58+
assert(!fs.existsSync(path));
59+
}));
60+
}
61+
62+
for (const linkTarget of linkTargets.map((p) => p + '-broken')) {
63+
for (const linkPath of linkPaths) {
64+
testSync(linkTarget, `${linkPath}-${path.basename(linkTarget)}-sync`);
65+
testAsync(linkTarget, `${linkPath}-${path.basename(linkTarget)}-async`);
66+
}
67+
}
68+
}

test/parallel/test-fs-symlink.js

+12
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@ fs.symlink(linkData, linkPath, common.mustCall(function(err) {
5858
}));
5959
}));
6060

61+
// Test invalid symlink
62+
{
63+
const linkData = fixtures.path('/not/exists/file');
64+
const linkPath = path.join(tmpdir.path, 'symlink2.js');
65+
66+
fs.symlink(linkData, linkPath, common.mustCall(function(err) {
67+
assert.ifError(err);
68+
69+
assert(!fs.existsSync(linkPath));
70+
}));
71+
}
72+
6173
[false, 1, {}, [], null, undefined].forEach((input) => {
6274
const errObj = {
6375
code: 'ERR_INVALID_ARG_TYPE',

0 commit comments

Comments
 (0)