summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBart Schaefer <schaefer@zsh.org>2025-10-26 19:42:56 -0700
committerBart Schaefer <schaefer@zsh.org>2025-10-26 19:42:56 -0700
commit005ef2c8307ea032341d6e493c004a02a6f1e785 (patch)
treed8583eb3d984c3d4de45c93cfa526eb632a88b49
parent53798: report reference loops created when a reference goes out of scope (diff)
downloadzsh-005ef2c8307ea032341d6e493c004a02a6f1e785.tar
zsh-005ef2c8307ea032341d6e493c004a02a6f1e785.tar.gz
zsh-005ef2c8307ea032341d6e493c004a02a6f1e785.tar.bz2
zsh-005ef2c8307ea032341d6e493c004a02a6f1e785.tar.lz
zsh-005ef2c8307ea032341d6e493c004a02a6f1e785.tar.xz
zsh-005ef2c8307ea032341d6e493c004a02a6f1e785.tar.zst
zsh-005ef2c8307ea032341d6e493c004a02a6f1e785.zip
53676+54009: Revise 52650+51945 for assignment to global through nameref
Allows assignment to a global via nameref to succeed without creating a dereference loop. Update tests for changed behavior.
-rw-r--r--ChangeLog4
-rw-r--r--Src/params.c7
-rw-r--r--Test/K01nameref.ztst28
3 files changed, 30 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 5785e858d..83d94c68f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -23,6 +23,10 @@
* Philippe: 53798: Src/params.c, Src/zsh.h, Test/K01nameref.ztst:
report reference loops created when a reference goes out of scope
+ * Philippe: 53676 (test tweaked per 54009): Src/params.c,
+ Test/K01nameref.ztst: Revise 52650+51945 to allow assignment to
+ global through nameref without looping
+
2025-10-24 Oliver Kiddle <opk@zsh.org>
* 54002: Src/parse.c: silence compiler warning for static function
diff --git a/Src/params.c b/Src/params.c
index aa948cf0c..df6a917b2 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -1044,13 +1044,12 @@ createparam(char *name, int flags)
if (oldpm && !(flags & PM_NAMEREF) &&
(oldpm->level == locallevel ?
!(oldpm->node.flags & PM_RO_BY_DESIGN) : !(flags & PM_LOCAL)) &&
- (oldpm->node.flags & PM_NAMEREF) &&
- (oldpm = upscope(oldpm, oldpm->base))) {
+ (oldpm->node.flags & PM_NAMEREF)) {
Param lastpm;
struct asgment stop;
stop.flags = PM_NAMEREF;
- stop.name = oldpm->node.nam;
- stop.value.scalar = GETREFNAME(oldpm);
+ stop.name = "";
+ stop.value.scalar = NULL;
lastpm = (Param)resolve_nameref(oldpm, &stop);
if (lastpm) {
if (lastpm->node.flags & PM_NAMEREF) {
diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst
index 460bc7260..de9707c5e 100644
--- a/Test/K01nameref.ztst
+++ b/Test/K01nameref.ztst
@@ -882,6 +882,21 @@ F:Checking for a bug in zmodload that affects later tests
>typeset -g var=RESET
unset -n ref
+ unset var1
+ typeset -n ref=var1
+ () {
+ typeset -n ref=var2
+ ref=RESET
+ typeset -p ref var2
+ }
+ typeset -p ref var2
+0:local reference hides same-name global reference
+>typeset -n ref=var2
+>typeset -g var2=RESET
+>typeset -n ref=var1
+>typeset -g var2=RESET
+
+ unset -n ref
unset one
typeset -n ref
typeset one=ONE
@@ -1045,14 +1060,17 @@ F:relies on global TYPESET_TO_UNSET in %prep
() {
typeset -n foo; foo=zz
foo=zz || print -u2 foo: assignment failed
- print $bar $zz
+ typeset -p bar zz
}
- () { typeset -n foo; foo=zz; local zz; foo=zz; print $bar $zz }
+ # prior to workers/53676 the assignment failed
+ unset zz
+ () { typeset -n foo; foo=zz; local zz; foo=zz; typeset -p bar zz }
0:regression: local nameref may not in-scope a global parameter
F:previously this could create an infinite recursion and crash
->xx
->xx zz
-*?*foo: assignment failed
+>typeset -g bar=xx
+>typeset -g zz=zz
+>typeset -g bar=xx
+>typeset zz=zz
typeset -nm foo=bar
1:create nameref by pattern match not allowed