jprichardson / node-fs-extra

Node.js: extra methods for the fs object like copy(), remove(), mkdirs()
MIT License
9.43k stars 775 forks source link

Copying a Link from One File to Another Link to the Same File errors out in `isSrcSubdir` #1019

Open cowsandmilk opened 10 months ago

cowsandmilk commented 10 months ago

Set up

touch testFile
ln -s testFile testLink1
ln -s testFile testLink2

Then, in node:

fs.copy('testLink1', 'testLink2');
Uncaught Error: Cannot copy 'testFile' to a subdirectory of itself, 'testFile'.

There are no directories involved here. The call to copyLink would succeed perfectly fine and do the correct thing in this case.

RyanZim commented 10 months ago

Yeah, that's a bug. Out of curiosity, how does Node's experimental fs.cp behave here?

cowsandmilk commented 10 months ago

how does Node's experimental fs.cp behave here?

apparently a similar error as fs-extra

> fs.cpSync('testLink1', 'testLink2')
Uncaught:
SystemError [ERR_FS_CP_EINVAL]: Invalid src or dest: cp returned EINVAL (cannot copy /private/tmp/node_fs_test/testFile to a subdirectory of self /private/tmp/node_fs_test/testFile) testLink2
    at __node_internal_captureLargerStackTrace (node:internal/errors:497:5)
    at new SystemError (node:internal/errors:257:5)
    at new NodeError (node:internal/errors:368:7)
    at onLink (node:internal/fs/cp/cp-sync:315:11)
    at getStats (node:internal/fs/cp/cp-sync:181:12)
    at checkParentDir (node:internal/fs/cp/cp-sync:159:10)
    at cpSyncFn (node:internal/fs/cp/cp-sync:61:10)
    at Object.cpSync (node:fs:2987:3) {
  code: 'ERR_FS_CP_EINVAL',
  info: {
    message: 'cannot copy /private/tmp/node_fs_test/testFile to a subdirectory of self /private/tmp/node_fs_test/testFile',
    path: 'testLink2',
    syscall: 'cp',
    errno: 22,
    code: 'EINVAL'
  },
  errno: [Getter/Setter: 22],
  syscall: [Getter/Setter: 'cp'],
  path: [Getter/Setter: 'testLink2']
}
RyanZim commented 10 months ago

Yeah, fs.cp is based on fse.copy, so apparently this bug is both places. Should be raised as an issue on Node as well, so we can both fix it.

Just to make sure I understand this, in this particular case, performing a copy wouldn't actually change anything about the makeup of the filesystem, correct?

cc @manidlou

cowsandmilk commented 10 months ago

performing a copy wouldn't actually change anything about the makeup of the filesystem, correct?

that would be my expectation

bstst commented 4 months ago

it does indeed look like there's an issue here.

I have an electron app packaged with vite. the @electron-forge/vite-plugin does fs.copy on the files of packages in the package.json file. My project has a dependency on the @smile-cdr/fhirts package. I get this error ("src:" and "dst:" are my debug logs, just as the "catch me" tracer):

src: /Users/martin/Projects/CENSORED/node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml
dst: /var/folders/bm/ytnswbdd57b5dm28zg7x8ysc0000gn/T/electron-packager/tmp-8AxS5d/Electron.app/Contents/Resources/app/node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml

Trace: catch me
    at /Users/martin/Projects/CENSORED/node_modules/fs-extra/lib/copy/copy.js:213:19
    at FSReqCallback.oncomplete (node:fs:200:23)

An unhandled rejection has occurred inside Forge:
Error: Cannot copy '../../../../../../esprima/bin/esvalidate.js' to a subdirectory of itself, '../../../../../../esprima/bin/esvalidate.js'.
at /Users/martin/Projects/CENSORED/node_modules/fs-extra/lib/copy/copy.js:214:21
    at FSReqCallback.oncomplete (node:fs:200:23)