Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
[PATCH] Fix saving and restoring of subscripted inline assignments
- X-seq: zsh-workers 54941
- From: Philippe Altherr <philippe.altherr@xxxxxxxxx>
- To: Zsh hackers list <zsh-workers@xxxxxxx>
- Subject: [PATCH] Fix saving and restoring of subscripted inline assignments
- Date: Fri, 10 Jul 2026 13:44:53 +0200
- Arc-authentication-results: i=1; mx.google.com; arc=none
- Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=to:subject:message-id:date:from:mime-version:dkim-signature; bh=C0BxBemka8TUsQy7iLR0LeV8pRqcNZAru/9zNQGETGE=; fh=BgAYDYpL6Ne/A5nWEMVJiHiBtrz8Imz3uf26RDwgQX4=; b=AapMGK5bZU0mhqBS6lr/roh65I3hGYHeINRN+pQYbcFSN06JKYyxtAdm7PKspbxpH2 KCGN/ERa7peOIlEMJV88uo0B9RT2LrnxvdThRE/zKx/HeW6vdVE8NFnXffFEU0eDYpuF zPBhTNn9sDp8mhUHwicY5DQvUBHhw6q25DX1rAu78Ke9B1Too5DE2mHqK22auG/FJmQU qox9WDJkcKqZqvxMMIP22U6TS/0YHhvadk/XIz6KmfqHU2zUBilfKWS1ljkgFHdZWblb q8AO/clq/nP639Q/hGDMlMyWtpWwi2G+JMV+Zvoq5b1rWlpln7teRtdsrqNN+tX+mpNG X3uQ==; darn=zsh.org
- Arc-seal: i=1; a=rsa-sha256; t=1783683905; cv=none; d=google.com; s=arc-20260327; b=rAq7QrrtMlBWImIMIQ62l8jJS3TZPvug39g7eTWqk+rhRIkwSGuijyNkW/1G+5BmAt If+PgkKmDbymH+/9SUTSCn3DkXfEbY4Jay8aGhWMCyU8zioVjmzv01fs6zW1TYU9nAwO SviBI7kYA9Q75KNkjnN8wBjqGqcfFVXh5p2Ri3DjfcVaKopceSQCuacQqEgQwJZKBwA8 4uybq8jJt5ecoihvC0b72IvUCyIZ3K8svRM6vzx514aGY2cObjdFCVxvfwCb8NBrlsjh woEpFYvdoYolagCPhuS/LQOZGWlS6NWSI9enImOZDPzS/3gZgcuGy/gPMPtqDDvLzisU Jz+g==
- Archived-at: <https://zsh.org/workers/54941>
- List-id: <zsh-workers.zsh.org>
When an external command is run with a subscripted inline assignment, the assigned parameter is restored to its previous value after the command returns:
% export var=12345
% var[2,4]=ABC printenv var
1ABC5
% typeset -p var
export var=12345
The same isn't true for builtins and user defined functions:
% myprintenv() { echo ${(P)1} }
% var[2,4]=ABC myprintenv var
1ABC5
% typeset -p var
export var=1ABC5
The former works because the parameter is only assigned in the forked process used to run the external command. Thus the value of the parameter remains unchanged in the main shell.
In the case of the latter, everything runs in the same process. There
is code to save and restore parameters modified by inline assignments but that code doesn't account for the fact that the assigned parameters may be subscripted. In the example above, it tries to save and restore the parameter var[2,4], instead of the parameter var, which naturally fails. This looks more like a bug than a feature. The patch below fixes it by taking into account the possible presence of subscripts.
Philippe
diff --git a/Src/exec.c b/Src/exec.c
index 17899262d..20caf40d1 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -4467,14 +4467,16 @@ static void
save_params(Estate state, Wordcode pc, LinkList *restore_p, LinkList *remove_p)
{
Param pm;
- char *s;
wordcode ac;
*restore_p = newlinklist();
*remove_p = newlinklist();
while (wc_code(ac = *pc) == WC_ASSIGN) {
- s = ecrawstr(state->prog, pc + 1, NULL);
+ char *s = ecrawstr(state->prog, pc + 1, NULL);
+ char *ss = itype_end(s, INAMESPC, 0);
+ int slen = *ss == '[' || *ss == Inbrack ? ss - s : strlen(s);
+ addlinknode(*remove_p, s = dupstring_wlen(s, slen));
if ((pm = (Param) paramtab->getnode(paramtab, s))) {
Param tpm = NULL;
if (pm->env)
@@ -4503,11 +4505,9 @@ save_params(Estate state, Wordcode pc, LinkList *restore_p, LinkList *remove_p)
tpm->node.nam = pm->node.nam;
copyparam(tpm, pm, 1);
}
- addlinknode(*remove_p, dupstring(s));
if (tpm)
addlinknode(*restore_p, tpm);
- } else
- addlinknode(*remove_p, dupstring(s));
+ }
pc += (WC_ASSIGN_TYPE(ac) == WC_ASSIGN_SCALAR ?
3 : WC_ASSIGN_NUM(ac) + 2);
diff --git a/Test/A06assign.ztst b/Test/A06assign.ztst
index d653d75b3..3cb73a3fe 100644
--- a/Test/A06assign.ztst
+++ b/Test/A06assign.ztst
@@ -539,12 +539,16 @@
call
HELLO=${HELLO}liness call
call
+ HELLO[2,4]=oo call
+ call
unset HELLO
0:save and restore when using original value in temporary
>world
>universe
>world
>worldliness
+>world
+>wood
>world
(integer i n x
Messages sorted by:
Reverse Date,
Date,
Thread,
Author