Skip to content

Commit cf9b301

Browse files
committed
fs: fix cp handle existing symlinks
1 parent ea79891 commit cf9b301

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

lib/internal/fs/cp/cp.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const {
5454
resolve,
5555
sep,
5656
} = require('path');
57+
const fsBinding = internalBinding('fs');
5758

5859
async function cpFn(src, dest, opts) {
5960
// Warn about using preserveTimestamps on 32-bit node
@@ -344,7 +345,10 @@ async function onLink(destStat, src, dest, opts) {
344345
if (!isAbsolute(resolvedDest)) {
345346
resolvedDest = resolve(dirname(dest), resolvedDest);
346347
}
347-
if (isSrcSubdir(resolvedSrc, resolvedDest)) {
348+
349+
const srcIsDir = fsBinding.internalModuleStat(src) === 1;
350+
351+
if (srcIsDir && isSrcSubdir(resolvedSrc, resolvedDest)) {
348352
throw new ERR_FS_CP_EINVAL({
349353
message: `cannot copy ${resolvedSrc} to a subdirectory of self ` +
350354
`${resolvedDest}`,

test/parallel/test-fs-cp.mjs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,23 @@ function nextdir(dirname) {
259259
cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true }));
260260
}
261261

262-
// It throws error if symlink in dest points to location in src.
262+
{
263+
const src = nextdir();
264+
const dest = nextdir();
265+
mkdirSync(src, mustNotMutateObjectDeep({ recursive: true }));
266+
writeFileSync(`${src}/test.txt`, 'test');
267+
symlinkSync(resolve(`${src}/test.txt`), join(src, 'link.txt'));
268+
cp(src, dest, { recursive: true },
269+
mustCall((err) => {
270+
assert.strictEqual(err, null);
271+
272+
cp(src, dest, { recursive: true }, mustCall((err) => {
273+
assert.strictEqual(err, null);
274+
}));
275+
}));
276+
}
277+
278+
// It allows copying symlinks in src to locations in dest with existing synlinks not pointing to a directory.
263279
{
264280
const src = nextdir();
265281
mkdirSync(join(src, 'a', 'b'), mustNotMutateObjectDeep({ recursive: true }));

0 commit comments

Comments
 (0)