* unset arbitrary associative array element
@ 2018-08-11 11:22 Stephane Chazelas
2018-08-11 14:55 ` Sebastian Gniazdowski
0 siblings, 1 reply; 4+ messages in thread
From: Stephane Chazelas @ 2018-08-11 11:22 UTC (permalink / raw)
To: Zsh hackers list
Hi,
one can set an arbitrary associative array element with:
typeset -A hash
hash[$key]=$value
But:
unset "hash[$key]"
Doesn't work for values of $key that contain "]" or "\" (or
characters whose encoding contain the bytes 0x5c or 0x5d) or for
an empty $key.
hash[$key]=()
doesn't work ("attempt to set slice of associative array"
error).
unset "hash[${key//(#m)[]\\]/\\$MATCH}]"
addresses keys with "]" and "\" but not those with characters
whose encoding contains 0x5c/5d or the empty key.
Is there any other way, other than recreating the full array
with something like:
hash=("${(@kv)hash[(I)^$key]}") # untested
ksh93 has the same kind of issues (plus various bugs for
characters that contain 0x5c/5d bytes), but supports unset
"hash[]" (even though like zsh it doesn't support hash[]=value).
In bash, one can do:
unset 'hash[$key]'
That is, the argument is evaluated as shell code! That means we
can unset arbitrary elements that way (though note that bash
doesn't support hash elements with empty keys!), but I would not
want to go there for bash as that means that things like
unset "hash[$key]"
are command injection vulnerabilities.
Not sure what's the best way to address it. Maybe like for
typeset and co, make "unset" a keyword where in
unset hash[$key]
That a[$key] is parsed the same way as in
hash[$key]=value
Or maybe a:
unset -k "$key" hash
Or
hash+=("$key") # add element without a value removes the element
In any case, it would be useful if we could set or unset the
element with the empty key with:
hash[]=value
unset "hash[]"
--
Stephane
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: unset arbitrary associative array element
2018-08-11 11:22 unset arbitrary associative array element Stephane Chazelas
@ 2018-08-11 14:55 ` Sebastian Gniazdowski
2018-08-12 3:38 ` Sebastian Gniazdowski
2018-08-12 6:06 ` Stephane Chazelas
0 siblings, 2 replies; 4+ messages in thread
From: Sebastian Gniazdowski @ 2018-08-11 14:55 UTC (permalink / raw)
To: Zsh hackers list
On Sat, 11 Aug 2018 at 13:22, Stephane Chazelas
<stephane.chazelas@gmail.com> wrote:
> Is there any other way, other than recreating the full array
> with something like:
>
> hash=("${(@kv)hash[(I)^$key]}") # untested
I once reported some unset-key impossibilities, and Bart and Peter
added a (b) flag. Maybe it helps here too. Could someone recall what
this flag does?
> --
> Stephane
--
Sebastian Gniazdowski
News: https://twitter.com/ZdharmaI
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: unset arbitrary associative array element
2018-08-11 14:55 ` Sebastian Gniazdowski
@ 2018-08-12 3:38 ` Sebastian Gniazdowski
2018-08-12 6:06 ` Stephane Chazelas
1 sibling, 0 replies; 4+ messages in thread
From: Sebastian Gniazdowski @ 2018-08-12 3:38 UTC (permalink / raw)
To: Zsh hackers list
I've found the post about (b) flag:
http://www.zsh.org/mla/workers/2016/msg00440.html
On Sat, 11 Aug 2018 at 16:55, Sebastian Gniazdowski
<sgniazdowski@gmail.com> wrote:
>
> On Sat, 11 Aug 2018 at 13:22, Stephane Chazelas
> <stephane.chazelas@gmail.com> wrote:
> > Is there any other way, other than recreating the full array
> > with something like:
> >
> > hash=("${(@kv)hash[(I)^$key]}") # untested
>
> I once reported some unset-key impossibilities, and Bart and Peter
> added a (b) flag. Maybe it helps here too. Could someone recall what
> this flag does?
>
> > --
> > Stephane
>
> --
> Sebastian Gniazdowski
> News: https://twitter.com/ZdharmaI
> IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
--
Sebastian Gniazdowski
News: https://twitter.com/ZdharmaI
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: unset arbitrary associative array element
2018-08-11 14:55 ` Sebastian Gniazdowski
2018-08-12 3:38 ` Sebastian Gniazdowski
@ 2018-08-12 6:06 ` Stephane Chazelas
1 sibling, 0 replies; 4+ messages in thread
From: Stephane Chazelas @ 2018-08-12 6:06 UTC (permalink / raw)
To: Sebastian Gniazdowski; +Cc: Zsh hackers list
2018-08-11 16:55:33 +0200, Sebastian Gniazdowski:
> On Sat, 11 Aug 2018 at 13:22, Stephane Chazelas
> <stephane.chazelas@gmail.com> wrote:
> > Is there any other way, other than recreating the full array
> > with something like:
> >
> > hash=("${(@kv)hash[(I)^$key]}") # untested
>
> I once reported some unset-key impossibilities, and Bart and Peter
> added a (b) flag. Maybe it helps here too. Could someone recall what
> this flag does?
[...]
Thanks Sebastian,
unset "hash[${(b)key}]"
does work for keys with "]" or "\" and for characters that
contain bytes 0x5c/5d, but not for the empty key.
Sounds like that problem can be fixed by allowing
unset 'hash[]'
like in ksh93. It would also be useful to allow
hash[]=value
as well (k=; hash[$k]=value and hash+=('' value) do work).
As for the characters with byte 0x5c in their content, that's a
more general problem.
If you want to test, try for instance:
LC_ALL=zh_HK.big5hkscs luit
And within luit:
hash[α]=foo
# and so on
α in BIG5 or BIG5-HKSCS is encoded as 0xa3 0x5c, 0x5c also being
the encoding of \. ${(b)key} for key='α' expands to α\ (0xa3
0x5c 0x5c).
That trailing 0x5c in the encoding of α is taken as a backslash
in many contexts in zsh.
Beside BIG5 and BIG5-HKSCS, GBK and GB18030 charsets also have
characters that contain 0x5c.
It may not be worth fixing if Chinese/Thai people have all
switched to UTF-8 by now.
--
Stephane
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-08-12 6:07 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-11 11:22 unset arbitrary associative array element Stephane Chazelas
2018-08-11 14:55 ` Sebastian Gniazdowski
2018-08-12 3:38 ` Sebastian Gniazdowski
2018-08-12 6:06 ` Stephane Chazelas
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).