Escape all literal dollar signs#3
Conversation
Signed-off-by: Bolun Thompson <bolunthompson@ucla.edu>
|
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 $ aThis test should not be allowed to run two roundtrips to pass, because the bug will be missed. |
6bf9708 to
df90dba
Compare
|
That plan sounds good to me! |
|
I added a github action to run the new shasta tests on PR, mostly copied from PaSh. Someone who has experience with actions should review it before merging — I’ve never written one before. |
angelhof
left a comment
There was a problem hiding this comment.
Thanks a lot @BolunThompson, that is great! The workflow looks fine except that we are not keeping track of the exit code of the tests now. Other than this, I was thinking whether it makes sense to only import libdash for tests (through pip or github, or with github first and pip as a backup, or vice versa) instead of having it as a submodule. What do people think?
ff1eb17 to
0b610b6
Compare
23a0169 to
8b7692e
Compare
d1e3ebf to
2279cd3
Compare
Prevents calling test setup every time the tests are run.
In principle, should resolve binpash/pash#664. If
cis 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.