Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 21 additions & 17 deletions lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -1793,23 +1793,27 @@ function symlink(target, path, type, callback) {
// Continue regardless of error.
}
if (absoluteTarget !== undefined) {
stat(absoluteTarget, (err, stat) => {
const resolvedType = !err && stat.isDirectory() ? 'dir' : 'file';
const resolvedFlags = stringToSymlinkType(resolvedType);
const destination = preprocessSymlinkDestination(target,
resolvedType,
path);

const req = new FSReqCallback();
req.oncomplete = callback;
binding.symlink(
destination,
path,
resolvedFlags,
req,
);
});
return;
try {
stat(absoluteTarget, (err, stat) => {
const resolvedType = !err && stat.isDirectory() ? 'dir' : 'file';
const resolvedFlags = stringToSymlinkType(resolvedType);
const destination = preprocessSymlinkDestination(target,
resolvedType,
path);

const req = new FSReqCallback();
req.oncomplete = callback;
binding.symlink(
destination,
path,
resolvedFlags,
req,
);
});
return;
} catch (statErr) {
// If stat fails, fall back to default symlink creation
}
}
}

Expand Down
38 changes: 38 additions & 0 deletions test/parallel/test-fs-symlink-windows-error-handling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Test for Windows symlink error handling when stat() fails
'use strict';

const common = require('../common');

// This test is specifically for Windows symlink behavior
if (!common.isWindows) {
common.skip('Windows-specific test');
}

if (!common.canCreateSymLink()) {
common.skip('insufficient privileges');
}

const assert = require('assert');
const fs = require('fs');
const path = require('path');
const tmpdir = require('../common/tmpdir');

tmpdir.refresh();

// Test that symlink creation doesn't crash when stat() fails on absoluteTarget
// This tests the try-catch error handling added around stat() call
const target = './nonexistent-target';
const linkPath = tmpdir.resolve('test-symlink');

// Create a symlink with a relative target that would cause stat() to fail
// when resolving the absolute target path
fs.symlink(target, linkPath, common.mustSucceed(() => {
// Verify the symlink was created successfully despite stat() error
fs.lstat(linkPath, common.mustSucceed((stats) => {
assert(stats.isSymbolicLink());
}));

fs.readlink(linkPath, common.mustSucceed((destination) => {
assert.strictEqual(destination, target);
}));
}));