ast
ast copied to clipboard
vi-mode filename completion with ~ corner-case bug
Description of problem:
When doing filename completion in vi-mode, if the path to be matched starts with ~, and is 6 characters long, and matches an existing file or dir, it expands to just '/home/'.
Ksh version:
Version AJM 93u+ 2012-08-01
How reproducible:
Steps to reproduce:
- touch ~/testfile
2.ls ~/test
Actual results:
expands to (visually) ls ~/tes/ but if you refresh the command at that point, it's really: ls /home/
Expected results:
expands to /home/username/testfile
Additional info:
It only happens if the pattern to be matched starts with ~ and is 6 chars long (which happens to be how long '/home/' is. It does not happen in emacs mode, so the problem appears to be in the vi edit code, not in the expansion code.
I can reproduce using ksh93u+ on Linux but not macOS. However, I cannot reproduce this using ksh built from the git master branch. So it looks like we've already fixed this; possibly by the fix for issue #1391 but more likely by one of the myriad fixes we've made for buffer overflows, use-after-free, and similar bugs.
@perlguy Can you build from source? If so can you confirm that you can no longer reproduce the problem?
Yeah... very sorry. I had built my own package on Arch using unmodified 2012-08-01-master. I forgot about that until you mentioned building from source. This bug is indeed fixed in the current master branch. I just checked the latest source, and it has the same fix I came up with of changing virtual[i] to virtual[last_virt]... (line 1717, edit/vi.c) Sorry to have wasted your time on this. :-)
So, maybe not a waste of time... 2020.0.0, used by mainstream Arch ksh package, the problem is slightly different. It expands correctly, but doesn't refresh the full line correctly... Now, if the 6th char in your input is a slash (e.g. mkdir ~/Test; ls ~/Test/<tab>
) it expands properly, but only overwrites the /
you were at when you hit ~
. Using ^L
to refresh the line shows the correct path. I'm working on building from latest source to see if it's fixed there or not.
When I follow the steps in your second reproducer both versions simply inserts a tab char without expanding the path. Both on macOS and Linux. If I omit the trailing slash and press [tab] the current source correctly expands the path while ksh93u+ exhibits the same problem in your first comment.
Check that the output of stty -a
looks reasonable. Especially with respect to the lines and columns.
Still not fixed in latest master (though the problem is slightly difference from 2012 version). I manually added lines showing ~
, and now, only when it ends in /
, on a dir with content (empty dir behaves normally).
[[email protected]: /home/jhelm]
$ Version A 2020.0.0-beta1-120-gc52d3a34
[[email protected]: /home/jhelm]
$ echo ${.sh.version}
Version A 2020.0.0-beta1-120-gc52d3a34
[[email protected]: /home/jhelm]
$ mkdir ~/Test
[[email protected]: /home/jhelm]
$ touch ~/Test/a
[[email protected]: /home/jhelm]
$ ls ~/Test/<tab>
$ ls ~/Testjhelm/Test/a<^L>
$ ls /home/jhelm/Test/a
my <tab>
got lost in the previous comment... should have read:
added lines showing <tab>
and <^L>
... but you probably figured that out.
Checked tty settings... and they are sane... tested with a variety of terminal sizes, all the same results.
Okay, creating a file in the directory I can reproduce what is presumably the same problem (although the behavior is slightly different) on macOS using the current git master branch:
KSH PROMPT:1: mkdir test
KSH PROMPT:2: touch test/a
KSH PROMPT:3: set -o vi
# Type `ls ~/test/` and press [tab]
KSH PROMPT:4: ls ~/test/krader/test/a/
# Press [ctrl-L]
KSH PROMPT:4: ls /Users/krader/test/a/
Emacs mode does not exhibit that problem.
Correct - it's Vi mode only, and you have captured the behavior perfectly.
Some of this sounds similar to something I reported a while back, but that got fixed. See issue #682.
Yes, @kusalananda, this seems to be the same as, or related to, issue #682. And I'm willing to bet a paycheck that it is due to the AST team being "too clever by half" for implementing a source code optimization that cannot be justified.