zsh-syntax-highlighting: zsh-syntax-highlighting breaks Zsh autocd for root entries

If there is a command in $PATH whose base name matches the basename of an entry under the root of the file tree (i.e., ‘/’) then AUTO_CD/autocd no longer works to cd to that directory (nor does the command get run).

To reproduce you should be able to do this on any version of Zsh from the past several years (I tried Zsh-5.5 through Zsh-5.7.1 and zsh-syntax-highlighting 0.5.0, 0.6.0, and the current dev in this github).

E.g., the LLVM package has a program called “opt” and most folks have a directory called “/opt”. So, with a mostly empty /etc/zsh/ (only a zshenv that sets ZDOTDIR only if it is not already set), this should reproduce:

(ZDOTDIR=/dev/null zsh -f)
host% setopt autocd
host% /opt
host% pwd
/opt
# Without z-s-highlighting it works fine.  Now activate z-s-highlighting:
host% . /usr/share/zsh/site-contrib/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
host% /opt
zsh: permission denied: /opt
host% opt -h     # This is the "opt" program from LLVM
opt: Unknown command line argument '-h'.  Try: 'opt -help'
opt: Did you mean '-S'?

If you don’t happen to already have LLVM installed then you can also just create a script called "usr" and chmod it 755, mv somewhere in $PATH and watch auto_cd fail for /usr. Most of the basenames in / on Linux are actually not such bad candidates for names of user scripts/programs, e.g., run, proc, dev, boot.

Oh, one more thing, the autocd does work if you put a trailing ‘/’ as in “/opt/”. Personally, I never remember that trailing slash and this bug drives me bananas, as if permissions on my /-files are messed up.

Not sure, but this could be a bug in Zsh that z-s-highlighting tickles. If you attach an strace to the Zsh just before you press ENTER (maybe with a -o/tmp/bug.st to catch the verbose output) the activity you can see shows that it verifies /usr/lib64/llvm/7/bin/opt as an executable regular file, not a directory, but then tries to execve("/opt") which naturally gets a permission denied. { I feel like EISDIR would be a more natural errno than the EACCES in this case, but that’s maybe some Linux kernel bitrot issue (man page suggests EISDIR, but kernel code seems to not do that anymore). I suspect this happens on non-Linux, too, but given the above, the issued error might vary. Yup…Just tested it on FreeBSD. Still says “permission denied”, though. Didn’t ktrace that one. }

I did look into the Zsh code and it mostly happens in a single C function that is about 1500 lines long. Since I’ve only been able to make it happen with with z-s-highlighting, chances seem good that some used hook perturbs logic just enough. Maybe this bug has arisen before, but I couldn’t find any evidence of that.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 19 (10 by maintainers)

Commits related to this issue

Most upvoted comments

Thanks for the pointer.

Re Cygwin - having no highlighting was one of the least painful aspects of that experience for me. I generally try to avoid Windows/Cygwin whenever possible. Probably best to let someone else performance debug that, but I do suspect the problem is process creation if someone ever wants to look into it/comes to this thread via a search.