Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: A serious bug in execution – where to debug?



On Wed, Jul 31, 2019 at 12:19 AM Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx> wrote:
>
> Roman Perepelitsa wrote on Tue, 30 Jul 2019 21:46 +00:00:
> > You should call `emulate -L zsh` from every functions that can be
> > called by any code other than yours. It's almost impossible to write
> > code that works the same way with all combinations of options. In my
> > public code I also unset aliases. These defensive measures reduce the
> > number of bug reports by *a lot*. People really seem to like creating
> > global aliases with single-letter names.
>
> z-sy-h also does 'emulate -L' and unsets aliases.

By the way, why does it deal with aliases manually instead of
`unsetopt aliases`?

>  I wonder if there
> should be a built-in way to do this, in order to make it easier to write
> plugins?  Perhaps a «source -U foo.zsh» syntax, as in autoload?

The only problem I have with `unsetopt aliases` is that it has to be
done before a function is parsed. This means using one of two
patterns:

1. Remember at the top of the file if `aliases` options is set, then
unset the option. At the bottom of the file, restore aliases.
2. Use two files. The first contains the real meet. The second has an
anonymous function with `emulate -L zsh && unsetopt alizes && source
first.zsh`.

The first is bound to sometimes fail to restore the options, which
causes catastrophic effects. The second requires two files makes
things a bit slower.

I use (2) with large files as it gives me the additional benefit of
being able to prevent extra loads of the file. The small file acts
like a header guard in C. Having the guarantee that my file is sourced
at most once gives many advantages.

> > I'll probably start calling `disable -f` for all builtins I use.
>
> I wonder if you might be throwing the baby out with the bathwater here.
> Aren't there legitimate use-cases for writing shadowing functions?  For
> example, what if somebody does «zle() { typeset -p funcstack >&2; zle "$@" }»
> for debugging purposes?

The flip side is that users often define functions with any name they
feel like and are none the wiser if they are shadowing some obscure
builtin your code needs. If you want to call the builtin, call the
builtin.

I'm on the fence on this issue. As long as I don't get too many bug
reports because of over-ambitious plugin managers, I'm fine. It does
get on my nerves sometimes though. If I could defend against functions
shadowing builtins easily, I would. I just don't know how. If
`builtin`, `disable`, `setopt`, `unsetopt`, `unset` and `unfunction`
are all hidden, escaping the sandbox is tricky.

Roman.



Messages sorted by: Reverse Date, Date, Thread, Author