Skip to content

Commit 366a45b

Browse files
pd4d10BethGriggs
authored andcommitted
fs: fix existsSync for invalid symlink at win32
Fixes: #30538 PR-URL: #30556 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 693099c commit 366a45b

4 files changed

Lines changed: 61 additions & 1 deletion

File tree

‎lib/fs.js‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,16 @@ function existsSync(path) {
228228
returnfalse;
229229
}
230230
constctx={ path };
231-
binding.access(pathModule.toNamespacedPath(path),F_OK,undefined,ctx);
231+
constnPath=pathModule.toNamespacedPath(path);
232+
binding.access(nPath,F_OK,undefined,ctx);
233+
234+
// In case of an invalid symlink, `binding.access()` on win32
235+
// will **not** return an error and is therefore not enough.
236+
// Double check with `binding.stat()`.
237+
if(isWindows&&ctx.errno===undefined){
238+
binding.stat(nPath,false,undefined,ctx);
239+
}
240+
232241
returnctx.errno===undefined;
233242
}
234243

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

Lines changed: 17 additions & 0 deletions
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+
constlinkData=fixtures.path('/not/exists/dir');
60+
constlinkPath=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‎

Lines changed: 22 additions & 0 deletions
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+
functiontestSync(target,path){
51+
fs.symlinkSync(target,path);
52+
assert(!fs.existsSync(path));
53+
}
54+
55+
functiontestAsync(target,path){
56+
fs.symlink(target,path,common.mustCall((err)=>{
57+
assert.ifError(err);
58+
assert(!fs.existsSync(path));
59+
}));
60+
}
61+
62+
for(constlinkTargetoflinkTargets.map((p)=>p+'-broken')){
63+
for(constlinkPathoflinkPaths){
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‎

Lines changed: 12 additions & 0 deletions
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+
constlinkData=fixtures.path('/not/exists/file');
64+
constlinkPath=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
consterrObj={
6375
code: 'ERR_INVALID_ARG_TYPE',

0 commit comments

Comments
 (0)