Skip to content

Commit 1b7ea01

Browse files
committed
fs: check subdir correctly in cpSync
1 parent 8b8fc53 commit 1b7ea01

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

src/node_file.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3193,7 +3193,8 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
31933193

31943194
std::string dest_path_str = dest_path.string();
31953195
// Check if dest_path is a subdirectory of src_path.
3196-
if (src_is_dir && dest_path_str.starts_with(src_path.string())) {
3196+
if (src_is_dir &&
3197+
dest_path.parent_path().string().starts_with(src_path.string())) {
31973198
std::string message = "Cannot copy " + src_path.string() +
31983199
" to a subdirectory of self " + dest_path.string();
31993200
return THROW_ERR_FS_CP_EINVAL(env, message.c_str());

test/parallel/test-fs-cp.mjs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ import tmpdir from '../common/tmpdir.js';
2424
tmpdir.refresh();
2525

2626
let dirc = 0;
27-
function nextdir() {
28-
return tmpdir.resolve(`copy_${++dirc}`);
27+
function nextdir(dirname) {
28+
return tmpdir.resolve(dirname || `copy_${++dirc}`);
2929
}
3030

3131
// Synchronous implementation of copy.
@@ -312,6 +312,32 @@ function nextdir() {
312312
);
313313
}
314314

315+
// It must not throw error if attempt is made to copy to dest
316+
// directory with same prefix as src directory
317+
// regression test for https://github.com/nodejs/node/issues/54285
318+
{
319+
const src = nextdir('prefix');
320+
const dest = nextdir('prefix-a');
321+
mkdirSync(src);
322+
mkdirSync(dest);
323+
cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true }));
324+
}
325+
326+
// It throws error if attempt is made to copy src to dest
327+
// when src is parent directory of the parent of dest
328+
{
329+
const src = nextdir('a');
330+
const destParent = nextdir('a/b');
331+
const dest = nextdir('a/b/c');
332+
mkdirSync(src);
333+
mkdirSync(destParent);
334+
mkdirSync(dest);
335+
assert.throws(
336+
() => cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true })),
337+
{ code: 'ERR_FS_CP_EINVAL' },
338+
)
339+
}
340+
315341
// It throws error if attempt is made to copy to subdirectory of self.
316342
{
317343
const src = './test/fixtures/copy/kitchen-sink';

0 commit comments

Comments
 (0)