-
Notifications
You must be signed in to change notification settings - Fork 2
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
Escape all literal dollar signs #3
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Bolun Thompson <[email protected]>
Wow, that is indeed suspiciously simple, lol. Does it work for this problematic case (binpash/pash#664 (comment))? Also, as an experiment, what does the parsed AST of this example look like? I am wondering why we need to diverge from the original libdash pretty printer though (https://github.com/binpash/libdash/blob/master/libdash/printer.py#L412). That printer seems to pass their roundtrip tests (https://github.com/binpash/libdash/tree/master/test). Could we somehow manage to run the roundtrip libdash tests here too? Is this issue exposed anywhere in the libdash tests? If not, should we add a test that exposes it? @mgree thoughts on this? Am I missing something? |
One more thought: I guess PaSh's usecase is special (and therefore maybe easier to handle) because when we call the pretty printer it is after the compiler is done and therefore everything has been expanded already, so any spare $ must be escaped? |
No, this looks like the correct printer fix. The libdash printer treats this correctly:
I don't know how the shasta printer diverged from the libdash one... |
I don't think the two printers diverge. I am seeing different behavior @mgree (after making libdash from source): $ cat ../../../../../f
echo '$1'
$ python3
Python 3.10.12 (main, Nov 6 2024, 20:22:13) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import libdash
>>> cmds = list(libdash.parse('f'))
>>> cmds
[(['Command', [1, [], [[['C', 101], ['C', 99], ['C', 104], ['C', 111]], [['Q', [['C', 36], ['C', 49]]]]], []]], "echo '$1'\n", 0, 1)]
>>> libdash.to_string(cmds[0][0])
'echo "$1"'
>>> Maybe you had f be $ cat f2
echo "\$x"
$ python3
Python 3.10.12 (main, Nov 6 2024, 20:22:13) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import libdash
>>> cmds = list(libdash.parse('f2'))
>>> cmds
[(['Command', [1, [], [[['C', 101], ['C', 99], ['C', 104], ['C', 111]], [['Q', [['E', 36], ['C', 120]]]]], []]], 'echo "\\$x"\n', 0, 1)]
>>> libdash.to_string(cmds[0][0])
'echo "\\$x"'
>>> The issue here seems to be with the single quote, and the fact that $ cat f4
echo $ a
## This is with the fix!
$ python3
Python 3.10.12 (main, Nov 6 2024, 20:22:13) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import libdash
>>> cmds = list(libdash.parse('f4'))
>>> cmds
[(['Command', [1, [], [[['C', 101], ['C', 99], ['C', 104], ['C', 111]], [['C', 36]], [['C', 97]]], []]], 'echo $ a\n', 0, 1)]
>>> libdash.to_string(cmds[0][0])
'echo \\$ a' Having the fix, it now always escapes the character Maybe the correct fix is to only escape the A larger issue here IMO is that we have two separate printer implementations. One in libdash and one in shasta (without any tests). My suggestion would be to: Also, it seems that libdash's tests fail to catch this issue, because they do two roundtrips (and in the second and third this is interpreted as a variable): $ cat ../test/failing/single-quote.sh
echo '$a'
echo $ a
$ ../test/round_trip.sh ./rt.py ../test/failing/single-quote.sh
PASS '../test/failing/single-quote.sh' (two runs to fixpoint)
## this is the output of `echo "$orig" "$rt" "$rtrt"`
/tmp/tmp.rgHMVGpsHK /tmp/tmp.y6EkOh0NEJ /tmp/tmp.6cK85M8VJb
$ cat /tmp/tmp.rgHMVGpsHK /tmp/tmp.y6EkOh0NEJ /tmp/tmp.6cK85M8VJb
echo "$a"
echo $ a
echo "${a}"
echo $ a
echo "${a}"
echo $ a |
Huh. My |
So I think the plan of action (to complete this PR) is the following. @BolunThompson let me know if you have any questions:
echo '$1'
echo $ a This test should not be allowed to run two roundtrips to pass, because the bug will be missed. |
6bf9708
to
df90dba
Compare
In principle, should resolve binpash/pash#664. If
c
is a literal dollar sign, it should be parsed as one (with no need to account for escaping & variable interpolation). Yet, this fix is suspiciously simple — is there an edge case here?The tests for PaSh still pass with this change.