thefuck icon indicating copy to clipboard operation
thefuck copied to clipboard

white-space safe 'thefuck' with the history line passed as a single arg?

Open Artoria2e5 opened this issue 8 years ago • 2 comments

In some shells' thefuck alias, e.g. for bash, the core part falls to:

# https://github.com/nvbn/thefuck/blob/master/thefuck/shells/bash.py#L13
eval $(BUNCH_OF_VARIABLES=something thefuck $(fc -ln -1)))

But $(fc -ln -1) is not a safe thing to try. In python terminology, $(fc -ln -1) is something like:

reduce(op.add, (glob.glob(i) or [i] for i in shell_stdout(['fc', '-ln', '-1']).split()))

which is almost certainly not the thing you are looking for. Similarly, $TF_CMD gets split and globbed and list-joined (and ' '.join()'ed by eval) in eval $TF_CMD.

For POSIX shells like bash and zsh (well, POSIX-ish) this can be solved by passing in the whole history string and actually interpreting the results of shlex.split(thestring) (which seems to be done already somewhere in the source). For other shells.. perhaps a custom lexer?

tcsh seems to suffer from the same problem, but I am not a tcsh expert so I may be wrong:

A2:~# sh -xvc ': "$@"' -- `echo 'foo bar /*'`
: "$@"
+ : foo bar /bin /boot /dev /etc /home /initrd.img /initrd.img.old /lib /lib32 /lib64 /libx32 /lost+found /media /mnt /opt /proc /pub /root /run /sbin /srv /sys /tmp /usr /var /vmlinuz /vmlinuz.old

(using sh for some arg dump that makes sense)

Artoria2e5 avatar Apr 01 '16 02:04 Artoria2e5

thefuck actually has a long way to go regarding whitespace/metachar-safety. Take 237f43e as an example (I found the cd issue when searching for 'whitespace' in issues to make sure that I didn't get a dup):

return 'cd "{0}"'.format(cwd)

This is unfortunately not the safe thing to do, e.g.:

cd "$(mktemp -d)"
mkdir aaaa\"
thefuck cd aaa

You will get some output like:

cd "/tmp/tmp.R71CQrZT1O/aaaa"" 

Unbalanced quotes.

The Right Thing™ to do is to actually use lists as the data structure for internal representation of single simple commands, i.e.

return ['cd', cwd]

And finally do some quoting based on shell-dependent rules before outputting (already there in the source). Note that POSIX shells don't consider quoted things like 'if' as keywords, and that's why I am putting emphasis on simple.

Artoria2e5 avatar Apr 01 '16 02:04 Artoria2e5

Yep, you're right. I'll think about how it can be made.

nvbn avatar Apr 06 '16 22:04 nvbn