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

lib: fix realpathSync resolving to invalid path (#54200) #54458

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
8 changes: 8 additions & 0 deletions lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -2731,6 +2731,14 @@ function realpathSync(p, options) {
}
resolvedLink = pathModule.resolve(previous, linkTarget);

// If resolvedLink is not valid or is a pipe/socket, stop resolving, break out of the loop
CGQAQ marked this conversation as resolved.
Show resolved Hide resolved
// issue: https://github.com/nodejs/node/issues/54200
CGQAQ marked this conversation as resolved.
Show resolved Hide resolved
const resolvedLinkStats = binding.lstat(resolvedLink, false, undefined, false /* throwIfNoEntry */);
if (!resolvedLinkStats || isFileType(resolvedLinkStats, S_IFIFO) ||
isFileType(resolvedLinkStats, S_IFSOCK)) {
break;
}

cache?.set(base, resolvedLink);
if (!isWindows) seenLinks.set(id, linkTarget);
}
Expand Down
38 changes: 38 additions & 0 deletions test/parallel/test-linux-dev-stdin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use strict';
const common = require('../common');
const tmpdir = require('../common/tmpdir');
const fs = require('fs');

//
// This test ensures Node.js doesn't crash when reading from /dev/stdin as an input.
// ref: https://github.com/nodejs/node/issues/54200
CGQAQ marked this conversation as resolved.
Show resolved Hide resolved
//

if (!fs.existsSync('/dev/stdin')) {
common.skip('Only test on platforms having /dev/stdin');
}

const child_process = require('child_process');
const assert = require('assert');
const { describe, it } = require('node:test');

describe('Test reading SourceCode from stdin and it\'s symlinks', () => {
it('Test reading sourcecode from /dev/stdin', () => {
const cp = child_process.execSync(`printf 'console.log(1)' | "${process.execPath}" /dev/stdin`, { stdio: 'pipe' });
assert.strictEqual(cp.toString(), '1\n');
});

it('Test reading sourcecode from a symlink to /dev/stdin', () => {
tmpdir.refresh();
const tmp = tmpdir.resolve('./stdin');
fs.symlinkSync('/dev/stdin', tmp);
const cp2 = child_process.execSync(`printf 'console.log(2)' | "${process.execPath}" ${tmp}`, { stdio: 'pipe' });
assert.strictEqual(cp2.toString(), '2\n');
});

it('Test reading sourcecode from a symlink to the `readlink /dev/stdin`', () => {
const devStdin = fs.readlinkSync('/dev/stdin');
const cp3 = child_process.execSync(`printf 'console.log(3)' | "${process.execPath}" "${devStdin}"`, { stdio: 'pipe' });

Check failure on line 35 in test/parallel/test-linux-dev-stdin.js

View workflow job for this annotation

GitHub Actions / test-macOS

--- stdout --- ▶ Test reading SourceCode from stdin and it's symlinks ✔ Test reading sourcecode from /dev/stdin (46.335792ms) ✔ Test reading sourcecode from a symlink to /dev/stdin (48.093417ms) ::debug::starting to run Test reading SourceCode from stdin and it's symlinks ::debug::starting to run Test reading sourcecode from /dev/stdin ::debug::completed running Test reading sourcecode from /dev/stdin ::debug::starting to run Test reading sourcecode from a symlink to /dev/stdin ::debug::completed running Test reading sourcecode from a symlink to /dev/stdin ✖ Test reading sourcecode from a symlink to the `readlink /dev/stdin` (43.749458ms) Error: Command failed: printf 'console.log(3)' | "/Users/runner/work/node/node/out/Release/node" "fd/0" node:internal/modules/cjs/loader:1251 throw err; ^ Error: Cannot find module '/Users/runner/work/node/node/fd/0' at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15) at Module._load (node:internal/modules/cjs/loader:1074:27) at TracingChannel.traceSync (node:diagnostics_channel:315:14) at wrapModuleLoad (node:internal/modules/cjs/loader:217:24) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:166:5) at node:internal/main/run_main_module:30:49 { code: 'MODULE_NOT_FOUND', requireStack: [] } Node.js v23.0.0-pre at genericNodeError (node:internal/errors:983:15) at wrappedFn (node:internal/errors:537:14) at checkExecSyncError (node:child_process:890:11) at Object.execSync (node:child_process:962:15) at TestContext.<anonymous> (/Users/runner/work/node/node/test/parallel/test-linux-dev-stdin.js:35:31) at Test.runInAsyncScope (node:async_hooks:211:14) at Test.run (node:internal/test_runner/test:885:25) at Suite.processPendingSubtests (node:internal/test_runner/test:582:18) at Test.postRun (node:internal/test_runner/test:981:19) at Test.run (node:internal/test_runner/test:924:12) { status: 1, signal: null, output: [ null, <Buffer >, <Buffer 6e 6f 64 65 3a 69 6e 74 65 72 6e 61 6c 2f 6d 6f 64 75 6c 65 73 2f 63 6a 73 2f 6c 6f 61 64 65 72 3a 31 32 35 31 0a 20 20 74 68 72 6f 77 20 65 72 72 3b ... 545 more bytes> ], pid: 67089, stdout: <Buffer >, stderr: <Buffer 6e 6f 64 65 3a 69 6e 74 65 72 6e 61 6c 2f 6d 6f 64 75 6c 65 73 2f 63 6a 73 2f 6c 6f 61 64 65 72 3a 31 32 35 31 0a 20 20 74 68 72 6f 77 20 65 72 72 3b ... 545 more bytes> } ▶ Test reading SourceCode from stdin and it's symlinks (138.933667ms) ::debug::starting to run Test reading sourcecode from a symlink to the `readlink /dev/stdin` ::error title=Test reading sourcecode from a symlink to the `readlink /dev/stdin`,file=test/parallel/test-linux-dev-stdin.js,line=35,col=31::[Error [ERR_TEST_FAILURE]: Command failed: printf 'console.log(3)' | "/Users/runner/work/node/node/out/Release/node" "fd/0" node:internal/modules/cjs/loader:1251 throw err; ^ Error: Cannot find module '/Users/runner/work/node/node/fd/0' at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15) at Module._load (node:internal/modules/cjs/loader:1074:27) at TracingChannel.traceSync (node:diagnostics_channel:315:14) at wrapModuleLoad (node:internal/modules/cjs/loader:217:24) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:166:5) at node:internal/main/run_main_module:30:49 { code: 'MODULE_NOT_FOUND', requireStack: [] } Node.js v23.0.0-pre ] { code: 'ERR_TEST_FAILURE', failureType: 'testCodeFailure', cause: Error: Command failed: printf 'console.log(3)' | "/Users/runner/work/node/node/out/Release/node" "fd/0" node:internal/modules/cjs/loader:1251 throw err; ^ Error: Cannot find module '/Users/runner/work/node/node/fd/0' at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15) at Module._load (node:internal/modules/cjs/loader:1074:27) at TracingChannel.traceSync (node:diagnostics
assert.strictEqual(cp3.toString(), '3\n');
});
});
Loading