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
8 changes: 3 additions & 5 deletions src/node_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4616,8 +4616,8 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {

std::error_code error_code;
auto src_status = dereference
? std::filesystem::symlink_status(src_path, error_code)
: std::filesystem::status(src_path, error_code);
? std::filesystem::status(src_path, error_code)
: std::filesystem::symlink_status(src_path, error_code);

if (error_code) {
#ifdef _WIN32
Expand All @@ -4635,9 +4635,7 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {

bool dest_exists = !error_code && dest_status.type() !=
std::filesystem::file_type::not_found;
bool src_is_dir =
(src_status.type() == std::filesystem::file_type::directory) ||
(dereference && src_status.type() == std::filesystem::file_type::symlink);
bool src_is_dir = src_status.type() == std::filesystem::file_type::directory;

auto src_path_str = ConvertPathToUTF8(src_path);
auto dest_path_str = ConvertPathToUTF8(dest_path);
Expand Down
42 changes: 42 additions & 0 deletions test/parallel/test-fs-cp-dereference-symlink-to-file.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// This tests that cp() and cpSync() copy the target file of a symlink passed
// as src when dereference is true and recursive is not set.

import { mustCall, mustNotMutateObjectDeep } from '../common/index.mjs';
import { nextdir } from '../common/fs.js';
import assert from 'node:assert';
import {
cp,
cpSync,
lstatSync,
mkdirSync,
readFileSync,
symlinkSync,
writeFileSync,
} from 'node:fs';
import { join } from 'node:path';
import tmpdir from '../common/tmpdir.js';

tmpdir.refresh();

const src = nextdir();
mkdirSync(src);
writeFileSync(join(src, 'foo.txt'), 'foo');
symlinkSync(join(src, 'foo.txt'), join(src, 'link.txt'));

const opts = mustNotMutateObjectDeep({ dereference: true });

{
const dest = join(nextdir(), 'foo.txt');
cpSync(join(src, 'link.txt'), dest, opts);
assert(lstatSync(dest).isFile());
assert.strictEqual(readFileSync(dest, 'utf8'), 'foo');
}

{
const dest = join(nextdir(), 'foo.txt');
cp(join(src, 'link.txt'), dest, opts, mustCall((err) => {
assert.ifError(err);
assert(lstatSync(dest).isFile());
assert.strictEqual(readFileSync(dest, 'utf8'), 'foo');
}));
}