fs: remove broken symlinks in rmSync

PR-URL: https://github.com/nodejs/node/pull/61040
Fixes: https://github.com/nodejs/node/issues/61020
Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Ulises Gascón <ulisesgascongonzalez@gmail.com>
This commit is contained in:
sangwook
2025-12-24 02:08:31 +09:00
committed by GitHub
parent c837811baf
commit dc8215b90d
2 changed files with 12 additions and 4 deletions

View File

@@ -1636,7 +1636,7 @@ static void RmSync(const FunctionCallbackInfo<Value>& args) {
env, permission::PermissionScope::kFileSystemWrite, path.ToStringView());
auto file_path = std::filesystem::path(path.ToStringView());
std::error_code error;
auto file_status = std::filesystem::status(file_path, error);
auto file_status = std::filesystem::symlink_status(file_path, error);
if (file_status.type() == std::filesystem::file_type::not_found) {
return;

View File

@@ -165,10 +165,13 @@ function removeAsync(dir) {
// Should delete an invalid symlink
const invalidLink = tmpdir.resolve('invalid-link-async');
fs.symlinkSync('definitely-does-not-exist-async', invalidLink);
assert.ok(fs.lstatSync(invalidLink).isSymbolicLink());
// `existsSync()` follows symlinks, so this confirms the target does not exist.
assert.strictEqual(fs.existsSync(invalidLink), false);
fs.rm(invalidLink, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall((err) => {
try {
assert.strictEqual(err, null);
assert.strictEqual(fs.existsSync(invalidLink), false);
assert.throws(() => fs.lstatSync(invalidLink), { code: 'ENOENT' });
} finally {
fs.rmSync(invalidLink, common.mustNotMutateObjectDeep({ force: true }));
}
@@ -247,11 +250,14 @@ if (isGitPresent) {
}
// Should delete an invalid symlink
// Refs: https://github.com/nodejs/node/issues/61020
const invalidLink = tmpdir.resolve('invalid-link');
fs.symlinkSync('definitely-does-not-exist', invalidLink);
assert.ok(fs.lstatSync(invalidLink).isSymbolicLink());
assert.strictEqual(fs.existsSync(invalidLink), false);
try {
fs.rmSync(invalidLink);
assert.strictEqual(fs.existsSync(invalidLink), false);
assert.throws(() => fs.lstatSync(invalidLink), { code: 'ENOENT' });
} finally {
fs.rmSync(invalidLink, common.mustNotMutateObjectDeep({ force: true }));
}
@@ -355,9 +361,11 @@ if (isGitPresent) {
// Should delete an invalid symlink
const invalidLink = tmpdir.resolve('invalid-link-prom');
fs.symlinkSync('definitely-does-not-exist-prom', invalidLink);
assert.ok(fs.lstatSync(invalidLink).isSymbolicLink());
assert.strictEqual(fs.existsSync(invalidLink), false);
try {
await fs.promises.rm(invalidLink);
assert.strictEqual(fs.existsSync(invalidLink), false);
assert.throws(() => fs.lstatSync(invalidLink), { code: 'ENOENT' });
} finally {
fs.rmSync(invalidLink, common.mustNotMutateObjectDeep({ force: true }));
}