Skip to content

Commit 00ad33d

Browse files
committed
fs: remove broken symlinks in rmSync
1 parent 28b1139 commit 00ad33d

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

src/node_file.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1636,7 +1636,7 @@ static void RmSync(const FunctionCallbackInfo<Value>& args) {
16361636
env, permission::PermissionScope::kFileSystemWrite, path.ToStringView());
16371637
auto file_path = std::filesystem::path(path.ToStringView());
16381638
std::error_code error;
1639-
auto file_status = std::filesystem::status(file_path, error);
1639+
auto file_status = std::filesystem::symlink_status(file_path, error);
16401640

16411641
if (file_status.type() == std::filesystem::file_type::not_found) {
16421642
return;

test/parallel/test-fs-rm.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,13 @@ function removeAsync(dir) {
165165
// Should delete an invalid symlink
166166
const invalidLink = tmpdir.resolve('invalid-link-async');
167167
fs.symlinkSync('definitely-does-not-exist-async', invalidLink);
168+
assert.ok(fs.lstatSync(invalidLink).isSymbolicLink());
169+
// `existsSync()` follows symlinks, so this confirms the target does not exist.
170+
assert.strictEqual(fs.existsSync(invalidLink), false);
168171
fs.rm(invalidLink, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall((err) => {
169172
try {
170173
assert.strictEqual(err, null);
171-
assert.strictEqual(fs.existsSync(invalidLink), false);
174+
assert.throws(() => fs.lstatSync(invalidLink), { code: 'ENOENT' });
172175
} finally {
173176
fs.rmSync(invalidLink, common.mustNotMutateObjectDeep({ force: true }));
174177
}
@@ -247,11 +250,14 @@ if (isGitPresent) {
247250
}
248251

249252
// Should delete an invalid symlink
253+
// Refs: https://github.com/nodejs/node/issues/61020
250254
const invalidLink = tmpdir.resolve('invalid-link');
251255
fs.symlinkSync('definitely-does-not-exist', invalidLink);
256+
assert.ok(fs.lstatSync(invalidLink).isSymbolicLink());
257+
assert.strictEqual(fs.existsSync(invalidLink), false);
252258
try {
253259
fs.rmSync(invalidLink);
254-
assert.strictEqual(fs.existsSync(invalidLink), false);
260+
assert.throws(() => fs.lstatSync(invalidLink), { code: 'ENOENT' });
255261
} finally {
256262
fs.rmSync(invalidLink, common.mustNotMutateObjectDeep({ force: true }));
257263
}
@@ -355,9 +361,11 @@ if (isGitPresent) {
355361
// Should delete an invalid symlink
356362
const invalidLink = tmpdir.resolve('invalid-link-prom');
357363
fs.symlinkSync('definitely-does-not-exist-prom', invalidLink);
364+
assert.ok(fs.lstatSync(invalidLink).isSymbolicLink());
365+
assert.strictEqual(fs.existsSync(invalidLink), false);
358366
try {
359367
await fs.promises.rm(invalidLink);
360-
assert.strictEqual(fs.existsSync(invalidLink), false);
368+
assert.throws(() => fs.lstatSync(invalidLink), { code: 'ENOENT' });
361369
} finally {
362370
fs.rmSync(invalidLink, common.mustNotMutateObjectDeep({ force: true }));
363371
}

0 commit comments

Comments
 (0)