fs: fix cp handle existing symlinks · nodejs/node@996fdb0

2 files changed

lines changed

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}`,

Original file line numberDiff line numberDiff line change

@@ -248,7 +248,7 @@ function nextdir(dirname) {

248248

);

249249

}

250250
251-

// It allows copying when is not a directory

251+

// It allows cpSync copying symlinks in src to locations in dest with existing synlinks not pointing to a directory.

252252

{

253253

const src = nextdir();

254254

const dest = nextdir();

@@ -259,6 +259,23 @@ function nextdir(dirname) {

259259

cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true }));

260260

}

261261
262+

// It allows cp copying symlinks in src to locations in dest with existing synlinks not pointing to a directory.

263+

{

264+

const src = nextdir();

265+

const dest = nextdir();

266+

mkdirSync(src, mustNotMutateObjectDeep({ recursive: true }));

267+

writeFileSync(`${src}/test.txt`, 'test');

268+

symlinkSync(resolve(`${src}/test.txt`), join(src, 'link.txt'));

269+

cp(src, dest, { recursive: true },

270+

mustCall((err) => {

271+

assert.strictEqual(err, null);

272+
273+

cp(src, dest, { recursive: true }, mustCall((err) => {

274+

assert.strictEqual(err, null);

275+

}));

276+

}));

277+

}

278+
262279

// It throws error if symlink in dest points to location in src.

263280

{

264281

const src = nextdir();