zsh-workers
 help / color / mirror / code / Atom feed
* 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).