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

cli: accept /dev/stdin as input file on Linux #13130

Closed
wants to merge 1 commit into from

Conversation

ebraminio
Copy link
Contributor

@ebraminio ebraminio commented May 20, 2017

  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines
Affected core subsystem(s)

cli

As mentioned above, tests will be added but for now, test it on Linux (macOS is OK) like this which with current version is broken:

make && echo "console.log(process.argv[2])" | ./node /dev/stdin --option-for-stdin-script

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. fs Issues and PRs related to the fs subsystem / file system. module Issues and PRs related to the module subsystem. labels May 20, 2017
Copy link
Contributor

@refack refack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion

src/node_file.cc Outdated
@@ -559,6 +560,9 @@ static void InternalModuleStat(const FunctionCallbackInfo<Value>& args) {
if (rc == 0) {
const uv_stat_t* const s = static_cast<const uv_stat_t*>(req.ptr);
rc = !!(s->st_mode & S_IFDIR);
if (rc == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a non hot-spot, I'd rather see an explicit if and rc = 2, similar to

if (rc == 0 && (s->st_mode & (S_IFIFO | S_IFSOCK))) {
  rc = 2;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, done

@refack refack added the blocked PRs that are blocked by other issues or PRs. label May 20, 2017
@refack
Copy link
Contributor

refack commented May 20, 2017

Added blocked until #13012 land, and the test case is added.

A question just for my information (since I'm not a posix expert): In the "simple" case node /dev/stdin it's a file, and in echo "console.log(process.argv[2])" | ./node /dev/stdin --option-for-stdin-script, /dev/stdin is a pipe?

@ebraminio
Copy link
Contributor Author

ebraminio commented May 20, 2017

When a process is piped, /dev/stdin will be a pipe (FIFO) normally.

echo "" | node -e "console.log(require('fs').statSync('/dev/stdin').isFIFO())"
(returns true)

But it seems in require('child_process').spawnSync(process.execPath, ['-e', code], { stdio: 'pipe' }) case, it can be a socket also that's why I am checking both at the same time.

node -e "console.log(require('child_process').spawnSync(process.execPath, ['-e', 'console.log(require(\'fs\').statSync(\'/dev/stdin\').isFIFO())'], { stdio: 'pipe' }).stdout.toString())"

(checks if /dev/stdin inside script piped with spawnSync is a pipe, which is false)

node -e "console.log(require('child_process').spawnSync(process.execPath, ['-e', 'console.log(require(\'fs\').statSync(\'/dev/stdin\').isSocket())'], { stdio: 'pipe' }).stdout.toString())"

(is a socket, true)

@refack
Copy link
Contributor

refack commented May 20, 2017

@ebraminio Thanks!

Follow Up: So what is s->st_mode on macOS (and maybe freeBSD), where you said curl pad.js.org | node /dev/stdin -h works?

@ebraminio
Copy link
Contributor Author

ebraminio commented May 20, 2017

macOS probably has same stat but its difference and advantage is on the fact that its /dev/stdin is just symlinked to /dev/fd/0 and there is nothing like /proc/self/fd/pipe:[289367] that can followed from there which can not be opened on nodejs in order to execute.

@Fishrock123
Copy link
Contributor

Will this make require('/dev/stdin') work? Should it?

Is that useful or potentially risky?

@refack
Copy link
Contributor

refack commented May 20, 2017

Will this make require('/dev/stdin') work? Should it?

Is that useful or potentially risky?

It's as bad as eval(userinput), or exec('node' ['-e', userinput]), or writeFile('./tmp.js', userInput); require('./tmp.js');
People who don't sanitize their user input are asking for trouble. Ref: https://xkcd.com/327/

@refack refack self-assigned this May 20, 2017
@ebraminio
Copy link
Contributor Author

ebraminio commented May 20, 2017

Will this make require('/dev/stdin') work? Should it?

It is already possible on macOS and possibly [not tested] other BSD derivations anyway.

lib/module.js Outdated
@@ -195,6 +195,8 @@ Module._findPath = function(request, paths, isMain) {
if (exts === undefined)
exts = Object.keys(Module._extensions);
filename = tryPackage(basePath, exts, isMain);
} else if (rc === 2) { // Pipe or Socket
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: two spaces before the comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed on new version as suitable comment on that version was something like neither file or directory which can be implied from the above.

src/node_file.cc Outdated
@@ -559,6 +560,9 @@ static void InternalModuleStat(const FunctionCallbackInfo<Value>& args) {
if (rc == 0) {
const uv_stat_t* const s = static_cast<const uv_stat_t*>(req.ptr);
rc = !!(s->st_mode & S_IFDIR);
if (rc == 0 && (s->st_mode & (S_IFIFO | S_IFSOCK))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not 100% convinced this is correct. Is there a reason you left out S_IFCHR?

My gut instinct is that the logic should look something like this:

if (S_ISREG(s->st_mode))
  rc = 0;
else if (S_ISDIR(s->st_mode))
  rc = 1;
else
  rc = 2;

(Whether that compiles on Windows is left as an exercise to the reader.)

Copy link
Contributor Author

@ebraminio ebraminio May 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That macro is not available but S_IFREG can be used it seems, done.

src/node_file.cc Outdated
@@ -546,7 +546,8 @@ static void InternalModuleReadFile(const FunctionCallbackInfo<Value>& args) {
}

// Used to speed up module loading. Returns 0 if the path refers to
// a file, 1 when it's a directory or < 0 on error (usually -ENOENT.)
// a file, 1 when it's a directory, 2 when is pipe or socket, or < 0 on
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to update the comment: "2 when it's anything else"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ops, done

Copy link
Contributor

@refack refack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 nit

Copy link
Member

@bnoordhuis bnoordhuis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. A regression test would be nice, though.

@ebraminio
Copy link
Contributor Author

ebraminio commented May 20, 2017

As this is unix only unlike the other patch, a separate test is added and this no longer blocked on that.

@refack refack removed the blocked PRs that are blocked by other issues or PRs. label May 20, 2017
@refack
Copy link
Contributor

refack commented May 20, 2017

Unblocked, but rename the test to start with the subsystem you are testing, something like: test-cli-arg-devstdin-posix.js, and update the first comment.

@refack
Copy link
Contributor

refack commented May 20, 2017

@ebraminio
Copy link
Contributor Author

ebraminio commented May 20, 2017

Hmmm, the logic seems not OK, hopefully temporary closing

@ebraminio ebraminio closed this May 20, 2017
@refack refack removed their assignment Oct 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. fs Issues and PRs related to the fs subsystem / file system. module Issues and PRs related to the module subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants