summaryrefslogtreecommitdiff
path: root/Src/Modules
diff options
context:
space:
mode:
authorBarton E. Schaefer <schaefer@zsh.org>2015-11-23 21:43:14 -0800
committerBarton E. Schaefer <schaefer@zsh.org>2015-11-23 21:43:14 -0800
commit4e90e27036d9bdaad71db895486f4895a5e6acf6 (patch)
tree0c3d92adf9c1585a08eecbb05f498a3e606aecf7 /Src/Modules
parentbc30d6bfca6f7b0a8578eecf468897975674d2b7 (diff)
downloadzsh-4e90e27036d9bdaad71db895486f4895a5e6acf6.tar.gz
zsh-4e90e27036d9bdaad71db895486f4895a5e6acf6.zip
37208: assignment in a nested scope should not change private parameters in the outer scope from unset to set
Bug remains that the attempt does not generate a warning
Diffstat (limited to 'Src/Modules')
-rw-r--r--Src/Modules/param_private.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/Src/Modules/param_private.c b/Src/Modules/param_private.c
index 7f9aa7921..7d1ba9c87 100644
--- a/Src/Modules/param_private.c
+++ b/Src/Modules/param_private.c
@@ -218,8 +218,10 @@ setfn_error(Param pm)
* The unsetfn family compare locallevel and restore the old GSU before
* calling the original unsetfn. This assures that if the old unsetfn
* wants to use its getfn or setfn, they're unconditionally present.
+ * The "explicit" flag indicates that "unset" was called, if zero the
+ * parameter is going out of scope (see params.c).
*
- */
+ */
/**/
static char *
@@ -248,13 +250,15 @@ pps_setfn(Param pm, char *x)
/**/
static void
-pps_unsetfn(Param pm, int x)
+pps_unsetfn(Param pm, int explicit)
{
struct gsu_closure *c = (struct gsu_closure *)(pm->gsu.s);
GsuScalar gsu = (GsuScalar)(c->g);
pm->gsu.s = gsu;
if (locallevel <= pm->level)
- gsu->unsetfn(pm, x);
+ gsu->unsetfn(pm, explicit);
+ if (explicit)
+ pm->gsu.s = (GsuScalar)c;
}
/**/
@@ -283,13 +287,15 @@ ppi_setfn(Param pm, zlong x)
/**/
static void
-ppi_unsetfn(Param pm, int x)
+ppi_unsetfn(Param pm, int explicit)
{
struct gsu_closure *c = (struct gsu_closure *)(pm->gsu.i);
GsuInteger gsu = (GsuInteger)(c->g);
pm->gsu.i = gsu;
if (locallevel <= pm->level)
- gsu->unsetfn(pm, x);
+ gsu->unsetfn(pm, explicit);
+ if (explicit)
+ pm->gsu.i = (GsuInteger)c;
}
/**/
@@ -318,13 +324,15 @@ ppf_setfn(Param pm, double x)
/**/
static void
-ppf_unsetfn(Param pm, int x)
+ppf_unsetfn(Param pm, int explicit)
{
struct gsu_closure *c = (struct gsu_closure *)(pm->gsu.f);
GsuFloat gsu = (GsuFloat)(c->g);
pm->gsu.f = gsu;
if (locallevel <= pm->level)
- gsu->unsetfn(pm, x);
+ gsu->unsetfn(pm, explicit);
+ if (explicit)
+ pm->gsu.f = (GsuFloat)c;
}
/**/
@@ -354,13 +362,15 @@ ppa_setfn(Param pm, char **x)
/**/
static void
-ppa_unsetfn(Param pm, int x)
+ppa_unsetfn(Param pm, int explicit)
{
struct gsu_closure *c = (struct gsu_closure *)(pm->gsu.a);
GsuArray gsu = (GsuArray)(c->g);
pm->gsu.a = gsu;
if (locallevel <= pm->level)
- gsu->unsetfn(pm, x);
+ gsu->unsetfn(pm, explicit);
+ if (explicit)
+ pm->gsu.a = (GsuArray)c;
}
static HashTable emptytable;
@@ -391,13 +401,15 @@ pph_setfn(Param pm, HashTable x)
/**/
static void
-pph_unsetfn(Param pm, int x)
+pph_unsetfn(Param pm, int explicit)
{
struct gsu_closure *c = (struct gsu_closure *)(pm->gsu.h);
GsuHash gsu = (GsuHash)(c->g);
pm->gsu.h = gsu;
if (locallevel <= pm->level)
- gsu->unsetfn(pm, x);
+ gsu->unsetfn(pm, explicit);
+ if (explicit)
+ pm->gsu.h = (GsuHash)c;
}
/*
@@ -425,9 +437,13 @@ scopeprivate(HashNode hn, int onoff)
pm->node.flags |= PM_NORESTORE;
else
pm->node.flags |= PM_UNSET;
- else if (!(pm->node.flags & PM_NORESTORE))
- pm->node.flags &= ~PM_UNSET;
- pm->node.flags &= ~PM_NORESTORE;
+ else {
+ if (pm->node.flags & PM_NORESTORE)
+ pm->node.flags |= PM_UNSET; /* createparam() may frob */
+ else
+ pm->node.flags &= ~PM_UNSET;
+ pm->node.flags &= ~PM_NORESTORE;
+ }
}
}