zx: $'s template strings broken with zx version 2
Hello! I noticed with version 2 most of my scripts broke. This is caused by this new function that adds a dollar and a quote in some specific conditions.
I don’t really understood the point of it so I prefer asking, is it an intended behavior? If so it would be great to add an explanation on the Readme and a note in a changelog documentation. If not would be glad to correct it 😃
Expected Behavior
echo '
const today = new Date()
$`echo "Today year is ${today.getFullYear()} and full date is ${today.toISOString()}"`
' > test.mjs
zx test.mjs
>>> Today year is 2021 and full date is 2021-07-15T16:18:35.288Z
Actual Behavior
echo '
const today = new Date()
$`echo "Today year is ${today.getFullYear()} and full date is ${today.toISOString()}"`
' > test.mjs
zx test.mjs
>>> Today year is 2021 and full date is $'2021-07-15T16:18:35.288Z'
Steps to Reproduce the Problem
- npm i -g zx
- Execute the lines I pasted before
Specifications
Works as expected with zx version 1.14.1
Broken on :
- Version: 2.0.0
- Platform: wsl2
Thanks for your help!
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 19
- Comments: 46 (1 by maintainers)
Seems like
zxonly struggles when the expression contains dashes.After going through the source code the issue IMO is a regex inside of quote function.
Instead of:
it should be
Because JS otherwise considers the dash to be range indicator (it matches all characters between
.and/= between 46 and 47 = only these two characters) and the dash is being ignored.You can easily test this:
I was able to get around this using:
As suggested by @YDSS, what about creting two commands to let the developper choose depending on its use case? Using the safe/unsafe keywords sometimes used in the web?
Use case 1: command’s parameters are not safe, and adding quotes could prevent a security vulnerability
Use case 2: command’s parameters are controlled by the developper, we can (and want to) accurately plan the template string’s output, no unexpected quotes are needed
I have the same issue with @smeijer and I understand the concern about security, but I think you can provide a way to disable the enhancement of “Quotes” feature, in my case I only want to it behave as a normal template string.
Is there a way to bypass the quoting/escaping? It makes it impossible to create function arguments dynamically.
For example:
I expect that to output:
But instead, the output is:
Which doesn’t work. Needless to say, that doesn’t have the expected result.
I suggest writing tests for those scenarios and fix these instances with pre/post processing to avoid the community hammering you with the same issues
Main reason why I’ve switched from Makefile / bash scripts is to use the power of a programming language to make my commands building easier to manage.
From a DX perspective, this behavior is really surprising and quite frankly a blocker for adoption IMO, all the expected benefits of command building disappear
I understand the security concerns but is there any solution that could make the above example works while still being secure ?
In the meantime, a workaround solution:
really? that should not happen…and why do you decide what context we consider unsafe? please don’t anticipate how users use it but instead add layered approach separating concerns, and add something like
$.safeinstead of the other way aroundWe already were thinking about the same API: https://github.com/google/zx/pull/151
But decided not to introduce it. It is dangerous and usually can be avoided altogether.
If you really need a command from a string there is a solution: use
child_processdirectly and provide safety on your own.Maybe sometimes it is desired to print quoted strings? Those should just be encoded correctly imo…
Definitely. I support your decision to not support unsafe operations. It’s your project after all. I just simply don’t get why my message sharing a workaround for those that do need it, got removed. But you explained it, and as I mentioned, your project, your issue tracker. So all fine now. 👍
Rejecting a feature/or saying no to additional configuration is also a part of an API design.
Sorry for hesitation. I don’t want show users not save way of using library. Didn’t mean any disrespect though.
I’ve been thinking about the security concern. Maybe it can detect a
--dry-runarg (or process.env var), and instead of executing the commands, only echo it? That way the user could dry run their script, and read if the commands line up with what they were expecting.As a bonus, that would also make it quite easy to wrap our scripts with tests.
but what if I want to
??
Omit quotes in echo.
Sure.
@antonmedv can you please create a new release with this fix? 😃