Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Race condition when 2 calls copying files to the same directory #142

Open
Soulike opened this issue Nov 26, 2021 · 0 comments
Open

Race condition when 2 calls copying files to the same directory #142

Soulike opened this issue Nov 26, 2021 · 0 comments

Comments

@Soulike
Copy link

Soulike commented Nov 26, 2021

The bug is similar to #141 but applies to files.
Before copying a file, ncp first checks whether the target file exists. If it exists (writable is false), ncp will delete it and start copying.

ncp/lib/ncp.js

Lines 221 to 229 in 6820b0f

function isWritable(path, done) {
fs.lstat(path, function (err) {
if (err) {
if (err.code === 'ENOENT') return done(true);
return done(false);
}
return done(false);
});
}

ncp/lib/ncp.js

Lines 84 to 97 in 6820b0f

function onFile(file) {
var target = file.name.replace(currentPath, targetPath);
if(rename) {
target = rename(target);
}
isWritable(target, function (writable) {
if (writable) {
return copyFile(file, target);
}
if(clobber) {
rmFile(target, function () {
copyFile(file, target);
});
}

So if 2 calls of ncp(), which copy files to the same directory, executes at almost the same time, the overwritten files in the target directory may be delete twice, and the latter one will throw error.

The test case below can reproduce the bug:

const sourceDir = '...dir path'
const tmpDir = path.join(os.tmpdir(), 'testFolder');

fs.rmSync(tmpDir, {recursive: true, force: true});
fs.mkdirSync(tmpDir);

ncp(sourceDir, tmpDir, function (err)
{
    if (err)
    {
        return console.error(err);
    }
    console.log('done!');

    ncp(sourceDir, tmpDir, function (err)
    {
        if (err)
        {
            return console.error(err);
        }
        console.log('done!');
    });

    ncp(sourceDir, tmpDir, function (err)
    {
        if (err)
        {
            return console.error(err);
        }
        console.log('done!');
    });
});

The execution result:

done!
[
   [Error: ENOENT: no such file or directory, unlink '/tmp/testFolder/xxxxx']
   [Error: ENOENT: no such file or directory, unlink '/tmp/testFolder/xxxxx']
    ...
]
done!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant