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

Unable to run globally installed node modules via this module #7

Open
tejashah88 opened this issue Mar 12, 2018 · 12 comments
Open

Unable to run globally installed node modules via this module #7

tejashah88 opened this issue Mar 12, 2018 · 12 comments

Comments

@tejashah88
Copy link

I'm not sure if this is a bug or intentional, but I've noticed that adding double quotes around any globally installed node modules (e.g. "npm") causes node to try and access it from your working directory. This actually causes this module to break since all the arguments are quoted. I tested this with the latest LTS release of node, which as of now is v8.10.0. It would be nice if there was either an alternate way to run these modules with this exec proxy or make a quick patch to allow this functionality with a small sacrifice to security.

@freitagbr
Copy link
Collaborator

Hi @tejashah88, can you provide a small example of some code that has this issue? Thanks.

@tejashah88
Copy link
Author

const shell = require('shelljs-exec-proxy');
shell.npm.install(); // throws an error here

This happens for pretty much any npm command, or as said before, any globally installed node modules.

@nfischer
Copy link
Owner

I tried the same code, I have no problem. Which OS? Are you changing your prefix (npm config get prefix)?

Double-quoting should not be a problem on unix. Double quoting essentially just means "interpret this literally, don't try any aliases, don't glob expand, don't expand things that look like variables." I'm also pretty sure double-quoting is OK on Windows: we rely on this for shell.exec() in shelljs.

@tejashah88
Copy link
Author

I am on windows, which might be why it's causing the problem.

Running npm config get prefix returns the following: C:\Users\<username>\AppData\Roaming\npm, which I haven't changed myself.

The error message indicates that it's trying to access the global module as if it was installed as a local dependency.

Error: Cannot find module 'C:\Users\<root_directory_of_project>\node_modules\npm\bin\npm-cli.js'

Sure enough, if I install npm locally (via npm install npm), and run the above code, then it runs like normal.

@nfischer
Copy link
Owner

@tejashah88 what's your PATH variable? Does it include the location of where you globally installed npm?

cmd> echo %PATH%

I think we use the same mechanism to find the locally-installed npm as we would to find the globally-installed npm: we just defer to PATH. npm run adds locally-installed modules to the PATH for you.

@tejashah88
Copy link
Author

Yes, it does include the location of where npm was globally installed.

@nfischer
Copy link
Owner

My windows machine isn't set up for development currently. @tejashah88 could you perhaps help debugging this?

What is the output of running npm test in this repo on your Windows machine? If anything fails, I would be interested to know. I'm also interested in seeing which tests output something like "skipping test" (such as in this line).

If you feel up for it, could you send a pull request which adds a test to execute a globally installed command? If you can repro with a builtin command, that would be great.

@tejashah88
Copy link
Author

So I ran the test scripts and interestingly, 5 tests failed, including all 3 that test for security.

Note that <root-dir> refers to the root directory of this module (when it was cloned from git).

  proxy
    √ appropriately handles inspect() and valueOf()
    √ returns appropriate keys
    √ does not override existing commands
    √ does not mess up non-command properties
    √ does not allow overriding reserved attributes
    √ does not allow deleting reserved attributes
    √ doesn't claim to have properties that don't exist in target
    √ allows adding new attributes
    commands
      - runs tr
      √ runs whoami (1265ms)
skipping test
      √ runs wc
skipping test
      √ runs du
skipping test
      √ runs rmdir
skipping test
      √ runs true
skipping test
      √ runs printf
      √ runs garbage commands (621ms)
      1) handles ShellStrings as arguments
    subcommands
      √ can use subcommands (673ms)
      √ can use subcommands with options (638ms)
      2) runs very long subcommand chains
    security
      3) handles unsafe filenames
      4) avoids globs
      5) escapes quotes


  17 passing (9s)
  1 pending
  5 failing

  1) proxy commands handles ShellStrings as arguments:

      AssertionError: expected true to be false
      + expected - actual

      -true
      +false

      at Assertion.fail (C:\<root-dir>\node_modules\should\cjs\should.js:326:17)
      at Assertion.value (C:\<root-dir>\node_modules\should\cjs\should.js:398:19)
      at Context.it (C:\<root-dir>\test\test.js:196:40)
      at callFnAsync (C:\<root-dir>\node_modules\mocha\lib\runnable.js:349:8)
      at Test.Runnable.run (C:\<root-dir>\node_modules\mocha\lib\runnable.js:301:7)
      at Runner.runTest (C:\<root-dir>\node_modules\mocha\lib\runner.js:422:10)
      at C:\<root-dir>\node_modules\mocha\lib\runner.js:528:12
      at next (C:\<root-dir>\node_modules\mocha\lib\runner.js:342:14)
      at C:\<root-dir>\node_modules\mocha\lib\runner.js:352:7
      at next (C:\<root-dir>\node_modules\mocha\lib\runner.js:284:14)
      at Immediate.<anonymous> (C:\<root-dir>\node_modules\mocha\lib\runner.js:320:5)

  2) proxy subcommands runs very long subcommand chains:

      AssertionError: expected '' to be 'one two three four five six seven\n'
      + expected - actual

      +one two three four five six seven

      at Assertion.fail (C:\<root-dir>\node_modules\should\cjs\should.js:326:17)
      at Assertion.value (C:\<root-dir>\node_modules\should\cjs\should.js:398:19)
      at Context.it (C:\<root-dir>\test\test.js:223:25)
      at callFnAsync (C:\<root-dir>\node_modules\mocha\lib\runnable.js:349:8)
      at Test.Runnable.run (C:\<root-dir>\node_modules\mocha\lib\runnable.js:301:7)
      at Runner.runTest (C:\<root-dir>\node_modules\mocha\lib\runner.js:422:10)
      at C:\<root-dir>\node_modules\mocha\lib\runner.js:528:12
      at next (C:\<root-dir>\node_modules\mocha\lib\runner.js:342:14)
      at C:\<root-dir>\node_modules\mocha\lib\runner.js:352:7
      at next (C:\<root-dir>\node_modules\mocha\lib\runner.js:284:14)
      at Immediate.<anonymous> (C:\<root-dir>\node_modules\mocha\lib\runner.js:320:5)

  3) proxy security handles unsafe filenames:

      AssertionError: expected true to be false
      + expected - actual

      -true
      +false

      at Assertion.fail (C:\<root-dir>\node_modules\should\cjs\should.js:326:17)
      at Assertion.value (C:\<root-dir>\node_modules\should\cjs\should.js:398:19)
      at Context.it (C:\<root-dir>\test\test.js:240:35)
      at callFnAsync (C:\<root-dir>\node_modules\mocha\lib\runnable.js:349:8)
      at Test.Runnable.run (C:\<root-dir>\node_modules\mocha\lib\runnable.js:301:7)
      at Runner.runTest (C:\<root-dir>\node_modules\mocha\lib\runner.js:422:10)
      at C:\<root-dir>\node_modules\mocha\lib\runner.js:528:12
      at next (C:\<root-dir>\node_modules\mocha\lib\runner.js:342:14)
      at C:\<root-dir>\node_modules\mocha\lib\runner.js:352:7
      at next (C:\<root-dir>\node_modules\mocha\lib\runner.js:284:14)
      at Immediate.<anonymous> (C:\<root-dir>\node_modules\mocha\lib\runner.js:320:5)

  4) proxy security avoids globs:

      AssertionError: expected 'hello world\r\n' to be 'hello world\n'
      + expected - actual

      -hello world
      +hello world

      at Assertion.fail (C:\<root-dir>\node_modules\should\cjs\should.js:326:17)
      at Assertion.value (C:\<root-dir>\node_modules\should\cjs\should.js:398:19)
      at Context.it (C:\<root-dir>\test\test.js:257:39)
      at callFnAsync (C:\<root-dir>\node_modules\mocha\lib\runnable.js:349:8)
      at Test.Runnable.run (C:\<root-dir>\node_modules\mocha\lib\runnable.js:301:7)
      at Runner.runTest (C:\<root-dir>\node_modules\mocha\lib\runner.js:422:10)
      at C:\<root-dir>\node_modules\mocha\lib\runner.js:528:12
      at next (C:\<root-dir>\node_modules\mocha\lib\runner.js:342:14)
      at C:\<root-dir>\node_modules\mocha\lib\runner.js:352:7
      at next (C:\<root-dir>\node_modules\mocha\lib\runner.js:284:14)
      at Immediate.<anonymous> (C:\<root-dir>\node_modules\mocha\lib\runner.js:320:5)

  5) proxy security escapes quotes:

      AssertionError: expected false to be true
      + expected - actual

      -false
      +true

      at Assertion.fail (C:\<root-dir>\node_modules\should\cjs\should.js:326:17)
      at Assertion.value (C:\<root-dir>\node_modules\should\cjs\should.js:398:19)
      at Context.it (C:\<root-dir>\test\test.js:267:36)
      at callFnAsync (C:\<root-dir>\node_modules\mocha\lib\runnable.js:349:8)
      at Test.Runnable.run (C:\<root-dir>\node_modules\mocha\lib\runnable.js:301:7)
      at Runner.runTest (C:\<root-dir>\node_modules\mocha\lib\runner.js:422:10)
      at C:\<root-dir>\node_modules\mocha\lib\runner.js:528:12
      at next (C:\<root-dir>\node_modules\mocha\lib\runner.js:342:14)
      at C:\<root-dir>\node_modules\mocha\lib\runner.js:352:7
      at next (C:\<root-dir>\node_modules\mocha\lib\runner.js:284:14)
      at Immediate.<anonymous> (C:\<root-dir>\node_modules\mocha\lib\runner.js:320:5)



---------------------|----------|----------|----------|----------|----------------|
File                 |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
---------------------|----------|----------|----------|----------|----------------|
 shelljs-exec-proxy\ |      100 |      100 |      100 |      100 |                |
  common.js          |      100 |      100 |      100 |      100 |                |
  index.js           |      100 |      100 |      100 |      100 |                |
---------------------|----------|----------|----------|----------|----------------|
All files            |      100 |      100 |      100 |      100 |                |
---------------------|----------|----------|----------|----------|----------------|

npm ERR! Test failed.  See above for more details.

@tejashah88
Copy link
Author

I am busy for now, but eventually, I'd love to submit a PR for testing this peculiarity.

@nfischer
Copy link
Owner

@tejashah88 thanks for the info!

Some of the tests look to have simple errors (one fails because Windows uses a different newline). I'll fix that test, look at the others, and try to set up appveyor to run CI on windows.

nfischer added a commit that referenced this issue Mar 17, 2018
This is one PR in a series to test and ensure Windows compatibility.

Issue #7
nfischer added a commit that referenced this issue Mar 17, 2018
This adds appveyor for Windows test coverage. As per issue #7, we expect
some Windows failures at this point. The intent is to land this first to
track Windows compatibility.

Issue #7
nfischer added a commit that referenced this issue Mar 17, 2018
This is one PR in a series to test and ensure Windows compatibility.

Issue #7
nfischer added a commit that referenced this issue Mar 17, 2018
This adds appveyor for Windows test coverage. As per issue #7, we expect
some Windows failures at this point. The intent is to land this first to
track Windows compatibility.

Issue #7
nfischer added a commit that referenced this issue Mar 17, 2018
This fixes some tests on Windows, some of which I actually broke in a
previous PR. This focuses on newlines: we need `\n` when comparing
against JavaScript strings, but `os.EOL` when comparing something from
the file system or the system's stdio.

Issue #7
nfischer added a commit that referenced this issue Mar 17, 2018
Windows doesn't support having quotes inside a filename, so we need to
skip this test.

Issue #7
nfischer added a commit that referenced this issue Mar 17, 2018
This fixes some tests on Windows, some of which I actually broke in a
previous PR. This focuses on newlines: we need `\n` when comparing
against JavaScript strings, but `os.EOL` when comparing something from
the file system or the system's stdio.

Issue #7
nfischer added a commit that referenced this issue Mar 17, 2018
Windows doesn't support having quotes inside a filename, so we need to
skip this test.

Issue #7
nfischer added a commit that referenced this issue Mar 17, 2018
This adds `shx` as a devdependency to test executing commands across
multiple platforms.

This also passes --noglob to avoid glob expansion from the shelljs
within shx, so that we can accurately test if we avoid the glob
expansion introduced from running shell.exec().

Issue #7
@nfischer
Copy link
Owner

Btw the tests should all pass (or will skip gracefully) on Windows now.

@tejashah88
Copy link
Author

Hey, thank you for working hard on this. Although I can't test if the original issue was fixed as I've switched Linux, I'll try it out on a virtual machine when I get some free time.

@nfischer nfischer added the bug label Feb 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants