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

memfs Symlinks do not provide correct behavior when traversing the link as a directory #1035

Open
tistocks opened this issue Jun 6, 2024 · 0 comments

Comments

@tistocks
Copy link

tistocks commented Jun 6, 2024

Given the following:

// symbolicLinkTest.ts
// src/symbolicLinkTest.ts
import * as osPath from 'path';
import { Volume, createFsFromVolume, IFs } from 'memfs';
import * as realFs from 'fs';

// Function to execute tasks
function executeTasks(fs: IFs) {
    // Define directories
    const testDir = osPath.join(__dirname, 'test-run');
    const targetDir = osPath.join(testDir, 'target');
    const linkDir = osPath.join(testDir, 'link');
    const targetSubDir = osPath.join(targetDir, 'subDir');
    const targetSubDirFile = osPath.join(targetSubDir, 'test.txt');

    // Create directory structure
    fs.mkdirSync(targetSubDir, { recursive: true });
    fs.writeFileSync(targetSubDirFile, "Hello World");
    fs.symlinkSync(targetDir, linkDir);

    // Function to check existence of a file through a link
    function checkFileExistence(linkPath: string, filePath: string) {
        const resolvedFilePath = osPath.join(linkPath, filePath);
        const resolvedDirPath = osPath.dirname(resolvedFilePath);
        console.log(`Does '${resolvedFilePath}' exist? ${fs.existsSync(resolvedFilePath)}`);
        console.log(`Of course it's a child of it's directory: ${fs.lstatSync(resolvedDirPath).isDirectory()}`);
    }

    // Test symbolic link
    console.log("Testing symbolic link:");
    checkFileExistence(linkDir, 'subDir/test.txt');
}

// Execute tasks with real file system (realFs)
console.log("Running with real file system (realFs):");
executeTasks(realFs as unknown as IFs);

// Create in-memory file system (memfs)
const vol = new Volume();
const memFs = createFsFromVolume(vol);

// Execute tasks with in-memory file system (memfs)
console.log("\nRunning with in-memory file system (memfs):");
executeTasks(memFs);

The following results are received:

% node symbolicLinkTest.js
Running with real file system (realFs):
Testing symbolic link:
Does '/Users/timothystockstill/symbolic-link-test/test-run/link/subDir/test.txt' exist? true
Of course it's a child of it's directory: true

Running with in-memory file system (memfs):
Testing symbolic link:
Does '/Users/timothystockstill/symbolic-link-test/test-run/link/subDir/test.txt' exist? true
/Users/timothystockstill/symbolic-link-test/node_modules/memfs/lib/volume.js:927
throw (0, util_1.createError)(ENOENT, 'lstat', filename);
^

Error: ENOENT: no such file or directory, lstat '/Users/timothystockstill/symbolic-link-test/test-run/link/subDir'
at createError (/Users/timothystockstill/symbolic-link-test/node_modules/memfs/lib/node/util.js:143:19)
at Volume.lstatBase (/Users/timothystockstill/symbolic-link-test/node_modules/memfs/lib/volume.js:927:42)
at Volume.lstatSync (/Users/timothystockstill/symbolic-link-test/node_modules/memfs/lib/volume.js:932:21)
at checkFileExistence (/Users/timothystockstill/symbolic-link-test/symbolicLinkTest.js:24:76)
at executeTasks (/Users/timothystockstill/symbolic-link-test/symbolicLinkTest.js:28:5)
at Object. (/Users/timothystockstill/symbolic-link-test/symbolicLinkTest.js:38:1)
at Module._compile (node:internal/modules/cjs/loader:1233:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1287:10)
at Module.load (node:internal/modules/cjs/loader:1091:32)
at Module._load (node:internal/modules/cjs/loader:938:12) {
code: 'ENOENT',
path: '/Users/timothystockstill/symbolic-link-test/test-run/link/subDir'
}

Node.js v20.5.0

Expected results:

No exception because the parent directory of the file that memFs confirmed to exist does in fact also exist (it has to).

I believe the problem is related to how getChild handles symlinks, when determining file path steps, but haven't fully investigated the code.

Is this expected behavior for memFs, is this a bug, is there a work around or will I need to look deeper at getChild?

@tistocks tistocks changed the title Symlinks do not provide correct behavior when traversing the link as a directory memfs Symlinks do not provide correct behavior when traversing the link as a directory Jun 6, 2024
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