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

Re: Bug in Functions/Misc/regexp-replace



Awesome, thanks for the expert response!

I vote for

eval "$1=\$5"

Jacob

On Fri, 30 Apr 2021 at 02:51, Stephane Chazelas <stephane@xxxxxxxxxxxx> wrote:
2021-04-29 19:53:52 -0400, Jacob Menke:
[...]
> regexp-replace str 'a' 'z' && echo $str
>
> Actual Output:
> (eval):1: bzd not found
>
> Expected:
> x :=bzd
[...]

One might argue there's a problem with the (q) parameter
expansion flag, it escapes leading =s but not the =s that follow
: even though they're special there in assignments.

$ echo a=x:=y
a=x:=y
$ a=x:=y
zsh: y not found

BTW, zsh is the only shell where ~ is expanded in:

$ zsh -c 'a=a\:~; echo $a'
a:/home/chazelas

[...]
> One way to fix:
> 41: eval ${1}=${(qqq)5}

The safest quoting operator is the (qq) one. I wouldn't use any
other for things to be reinput to the shell.

See
https://unix.stackexchange.com/questions/379181/escape-a-variable-for-use-as-content-of-another-script/600214#600214
for details on that.

In particular qqq uses double quotes inside which \ and ` are
still special and those characters also appear in the encoding
of some other characters in some locales.

But here, the best thing to do is to not expose the parser to
the contents of $5 by doing:

eval "$1=\$5"

(which tells the shell to evaluate varname=$5)

You need to expand $1 here which contains the variable name.

Note that as already noted at
https://www.zsh.org/mla/workers/2019/msg01113.html
whether you use that or

: ${(P)1::="$5"}

You'll still have a command injection vulnerability if $1 is not
guaranteed to be a variable name.

--
Stephane


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