-
Notifications
You must be signed in to change notification settings - Fork 778
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
copy and copySync can fail with 'Source and destination must not be the same' #657
Comments
yeah but we should note that |
This is pretty bad and makes tools that depend on this library very unreliable :( As a consumer, is there anything that can be done to work around this issue? |
Yeah I agree we need to fix this! |
Can you elaborate on the intention of the check? My thoughts were, if it was intentional to not just check source against destination filename, the intention was to not copy files where the source and destination are some sort of link from one to the other. In which case a copy of a link onto its target or vice versa should be prevented. I'm not sure what the outcome would be of such a copy operation, but I guess it's undesirable or will fail. Sadly, in my test case, the entire In case the check is in place to prevent failures, I think the only solution is to just let the process fail, catch the error and handle it appropriately. |
@oliversalzburg, we mainly check paths to ensure
|
I know you are not a fan of native dependencies, but I'd also like to mention the option I also offered in #626, a small piece of native code to work around the specific problem on Windows when |
From the end user perspective the situation is the same as if the destination is different, but already exists. The fact that
So in both cases we have to catch and identify the error, so it should provide an error code. For illustration: async function tryCopy() {
try {
await copy(src, dest, {
overwrite: false,
errorOnExist: true,
});
} catch (error) {
if (error.code === 'EEXIST'
// These are now additionally required:
// || error.message === 'Source and destination must not be the same'
// || error.message === `'${dest}' already exists`
) {
iter++;
dest = `${originalDest} (${iter})`
return await tryCopy();
}
throw error;
}
} EDIT: hm .. how do I handle this with directories? I suppose I would need the ability to provide EDIT2: On win: copyFile(dir, dir) // EPERM
copyFile(file, file) // EBUSY
copyFile(file, file, Fs.constants.COPYFILE_EXCL) // EEXIST |
For the time being, would you accept a patch that allows |
@manidlou If I understood this correctly, NodeJS FS returns or for And / or just let the system decide when a copy operation has to be failed. Remove the checkPath-feature. Or disable it by option. ... PS: We could add the |
@jprichardson @manidlou I recommend to increase the priority of this issue. It's a critical bug. As I suggested: Enable bigint if supported. And / or remove the checkPaths method (as option or always). |
I will work on this and try to have a PR ASAP! However, I am not a fan of not checking the paths by default because that means we clearly ship the buggy code because of issues like #83, #565 and alike! But I am open to have the checkPaths as an option and let users decide how copy should be handled. |
@manidlou Thanks. 🙂 Btw. we could also enable the bigint feature. Yes, I know that this is a Node 10.4 feature. And not supported for older Node versions. But this library could only enable it, if it is supported. And if people has problems with the checkPaths cuz state.ino, they can just update Node and all's fine. Finally, I don't know the inode (state.ino) value on a failue. We should log this to the error. (just add the value to the error text. (both values from destStat and srcStat). To see, is this a higher value than 53-bit or maybe Files with checkPaths (state.ino): |
In all my tests, the inode was always a valid integer. The source is the issue nodejs/node#12115 as described in the original post. I might have another suggestion too maybe. Given that this is a Windows-specific issue, how about this:
The motivation being to leave as much code as possible as-is, and just focus on the problematic scenario, which could also allow for easy removal once older Node version support is dropped. |
I'm wondering why is this a Windows-only issue. Maybe the other systems uses smaller integers?
And here's a demonstration of big integer.
If the value of inode were a string, then we would not have any problems. But bigint will also solves it. |
You know there's a very long issue with all the details that has been linked here several times now, right? 😉 |
@oliversalzburg Hehe, sorry. I'm lazy in reading. 😄 |
NOTE 🚩 |
Should be fixed in |
This should be re-opened. It's only fixed for Node 10.5+. I'm proposing a fix that would also work (or at least provide a much smaller chance of this happening) in #667 (comment), and I could open a PR for it. Thoughts? |
Yes, assuming that there is sufficient desire to support the older Node.js versions. Note that Node.js version 8 EOL is coming this December and older versions are already past EOL. |
A lot of effort has been put into this to both fix it, and yet maintain backward-compatibility with older Node versions. December is still far, and this issue exists now. My proposed fix is simple, straightforward, local, and practically solves this issue for those who would use it for the next 6 months. Or, for anyone using an older Node 10 version that can't (for whatever reason) update to 10.5+. Besides, once a Node versions goes in EOL, it doesn't necessarily mean that it stops working - it just won't get fixes and updates anymore, and some devs might be perfectly fine with that. |
@mbargiel I do not see a proposal from you to resolve the issue on older Node.js versions. Did I miss anything here? |
Sorry - I probably should have quoted myself.
My reasoning is that since By checking other stats that should be the same for hardlinks, we can reduce this window - that's practically free since included in the In addition, it provides an easy way for users still hitting this problem in some automated scenarios to avoid it: using different owners, modes, timestamps, contents, etc. just to make sure the source and dest paths differ in some way. |
I'll take a shot at a PR, and you can comment on it. I'll post the link here. |
So any solutions? |
Any updates on that? I'm still having this problem |
@manidlou Your call on what to do here. |
See #694 for a proposed "fix". |
fs-extra
version:7.0.0copy and copySync will fail with 'Source and destination must not be the same' when node occasionally returns the same ino for different files due to a bigint rounding issue (nodejs/node#12115). The solution is probably to set options parameter to { bigint: true } when calling fstat (https://nodejs.org/api/fs.html#fs_fs_fstat_fd_options_callback) from the checkPaths function of copy.js and copy-sync.js.
The text was updated successfully, but these errors were encountered: