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

Not expanding unquoted variables correctly #1

Open
pdpwebsecurify opened this issue Oct 21, 2022 · 8 comments
Open

Not expanding unquoted variables correctly #1

pdpwebsecurify opened this issue Oct 21, 2022 · 8 comments
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@pdpwebsecurify
Copy link

Consider the following example:

$ export T="c d"
$ node -e 'console.log(JSON.stringify(process.env.T), process.argv)' a b $T

You get the following result:

"c d" [
  '/home/ec2-user/.nvm/versions/node/v17.0.1/bin/node',
  'a',
  'b',
  'c',
  'd'
]

The variable T is expanded in possitional args c and d. If we quote the variable then we get a different result:

$ export T="c d"
$ node -e 'console.log(JSON.stringify(process.env.T), process.argv)' a b "$T"
"c d" [
  '/home/ec2-user/.nvm/versions/node/v17.0.1/bin/node',
  'a',
  'b',
  'c d'
]

However, in the shell-quote library the situation is different. Consider the following example:

const shellQuote = require('shell-quote')

console.log(shellQuote.parse('test a b $T', { T: 'c d' }))

We get the following result:

[ 'test', 'a', 'b', 'c d' ]

Notice that the behaviour is different as in the variable T does not get expanded. In other words, the behaviour is similar to variable T beign quoted, i.e:

const shellQuote = require('shell-quote')

console.log(shellQuote.parse('test a b "$T"', { T: 'c d' })) // [ 'test', 'a', 'b', 'c d' ]

If shell-quote is used to parse string which are used to spown a process with environment variable that are not quoted, it will result in a completely different behaviour than the one expected from the standard shell.

@ljharb
Copy link
Owner

ljharb commented Oct 21, 2022

interesting - this makes sense, that the presence of quotes should matter.

Are there existing tests that would break with this change?

@pdpwebsecurify
Copy link
Author

I have no idea. I was planning to use this library but it seems that at the moment it will not be a good fit due to this particular bug.

@ljharb
Copy link
Owner

ljharb commented Oct 22, 2022

I'd love to review a PR that fixes it and adds tests :-)

ljharb added a commit that referenced this issue Apr 7, 2023
@ljharb
Copy link
Owner

ljharb commented Apr 7, 2023

I've pushed up a branch with failing tests, and found the place where the unquoted env var is retrieved.

The difficulty is essentially that the current approach inlines env vars amidst parsing - however, an unquoted env var needs to be treated as part of the parse, and at this point in the implementation, we've already tokenized the input - and it's tricky to insert more tokens into the list.

@ljharb ljharb added bug Something isn't working help wanted Extra attention is needed labels Apr 7, 2023
@drok
Copy link

drok commented Nov 5, 2023

Isn't this a matter of porting an existing shell's grammar parser to js?

Here are the interesting bits from bash:

https://git.savannah.gnu.org/cgit/bash.git/tree/parse.y (Yacc grammar for bash)
https://git.savannah.gnu.org/cgit/bash.git/tree/subst.c (The part of the shell that does parameter, command, arithmetic, and globbing substitutions)

These two files account for probably 60% of what bash is.

Supporting ${T} is not that far off from $T, and you'd have to support brace expansion for cases like abc${T}def. Then, what about ${T[1]} or $1 or $PID or $((T*2)) or $(echo $T | sed s/-/_/g) ?

Are there practical applications to handling shell variable expansion in a javascript program? Can we really take shell variables out of the shell?

@ljharb
Copy link
Owner

ljharb commented Nov 5, 2023

There are many more shells than bash, and porting a parser would be extremely brittle since that can change drastically across even a single shell's major versions.

@drok
Copy link

drok commented Nov 5, 2023

There are many more shells than bash, and porting a parser would be extremely brittle since that can change drastically across even a single shell's major versions.

I whole heartedly agree, and I think it's more sensible to remove variable expansion from the library, rather than attempt to fix it. I'm leaning towards removing this feature from my fork.

@ljharb
Copy link
Owner

ljharb commented Nov 5, 2023

We won’t ever be removing any features; breaking changes are toxic to the ecosystem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants