Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH] Don't perform dereferencing when looking up certain special parameters



The code managing a number of special parameters performs dereferencing while looking up the parameter. This often leads to bogus behavior. Here is an example:

% typeset -n PWD=pwd
% cd /
% typeset -p PWD pwd
typeset -n PWD=pwd
export pwd=/
% printenv | grep -i ^PWD=
pwd=/

In this case, the wrong parameter is exported. In many cases, the fix is to simply not perform any dereferencing, which is what the following patch does for a number of special parameters.

Don't perform dereferencing when looking up certain special parameters

Philippe

diff --git a/Src/Modules/watch.c b/Src/Modules/watch.c
index f23819b25..8704795e6 100644
--- a/Src/Modules/watch.c
+++ b/Src/Modules/watch.c
@@ -746,9 +746,9 @@ boot_(UNUSED(Module m))
     /* These two parameters are only set to defaults if not set.
      * So setting them in .zshrc will not be enough to load the
      * module. It's useless until the watch array is set anyway. */
-    if (!paramtab->getnode(paramtab, "WATCHFMT"))
+    if (!realparamtab->getnode2(realparamtab, "WATCHFMT"))
 	setsparam("WATCHFMT", ztrdup_metafy(default_watchfmt));
-    if (!paramtab->getnode(paramtab, "LOGCHECK"))
+    if (!realparamtab->getnode2(realparamtab, "LOGCHECK"))
 	setiparam("LOGCHECK", 60);
 
     addprepromptfn(&checksched);
diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c
index 230ad86f6..18dcf5519 100644
--- a/Src/Modules/zftp.c
+++ b/Src/Modules/zftp.c
@@ -496,7 +496,7 @@ zfsetparam(char *name, void *val, int flags)
     Param pm = NULL;
     int type = (flags & ZFPM_INTEGER) ? PM_INTEGER : PM_SCALAR;
 
-    if (!(pm = (Param) paramtab->getnode(paramtab, name))
+    if (!(pm = (Param) realparamtab->getnode2(realparamtab, name))
 	|| (pm->node.flags & PM_UNSET)) {
 	/*
 	 * just make it readonly when creating, in case user
@@ -530,7 +530,7 @@ zfunsetparam(char *name)
 {
     Param pm;
 
-    if ((pm = (Param) paramtab->getnode(paramtab, name))) {
+    if ((pm = (Param) realparamtab->getnode2(realparamtab, name))) {
 	pm->node.flags &= ~PM_READONLY;
 	unsetparam_pm(pm, 0, 1);
     }
diff --git a/Src/builtin.c b/Src/builtin.c
index ff9cf57f9..7f9c49f8a 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -803,13 +803,13 @@ set_pwd_env(void)
 
     /* update the PWD and OLDPWD shell parameters */
 
-    pm = (Param) paramtab->getnode(paramtab, "PWD");
+    pm = (Param) realparamtab->getnode2(realparamtab, "PWD");
     if (pm && PM_TYPE(pm->node.flags) != PM_SCALAR) {
 	pm->node.flags &= ~PM_READONLY;
 	unsetparam_pm(pm, 0, 1);
     }
 
-    pm = (Param) paramtab->getnode(paramtab, "OLDPWD");
+    pm = (Param) realparamtab->getnode2(realparamtab, "OLDPWD");
     if (pm && PM_TYPE(pm->node.flags) != PM_SCALAR) {
 	pm->node.flags &= ~PM_READONLY;
 	unsetparam_pm(pm, 0, 1);
@@ -818,10 +818,10 @@ set_pwd_env(void)
     assignsparam("PWD", ztrdup(pwd), 0);
     assignsparam("OLDPWD", ztrdup(oldpwd), 0);
 
-    pm = (Param) paramtab->getnode(paramtab, "PWD");
+    pm = (Param) realparamtab->getnode2(realparamtab, "PWD");
     if (!(pm->node.flags & PM_EXPORTED))
 	addenv(pm, pwd);
-    pm = (Param) paramtab->getnode(paramtab, "OLDPWD");
+    pm = (Param) realparamtab->getnode2(realparamtab, "OLDPWD");
     if (!(pm->node.flags & PM_EXPORTED))
 	addenv(pm, oldpwd);
 }
diff --git a/Src/init.c b/Src/init.c
index 7c3b82461..b9aef93da 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -179,7 +179,7 @@ loop(int toplevel, int justonce)
 	    non_empty = 1;
 	    if (toplevel &&
 		(getshfunc("preexec") ||
-		 paramtab->getnode(paramtab, "preexec" HOOK_SUFFIX))) {
+		 realparamtab->getnode2(realparamtab, "preexec" HOOK_SUFFIX))) {
 		LinkList args;
 		char *cmdstr;
 
diff --git a/Src/module.c b/Src/module.c
index 0b5cd5649..049394a5b 100644
--- a/Src/module.c
+++ b/Src/module.c
@@ -1027,7 +1027,7 @@ checkaddparam(const char *nam, int opt_i)
 {
     Param pm;
 
-    if (!(pm = (Param) gethashnode2(paramtab, nam)))
+    if (!(pm = (Param) realparamtab->getnode2(realparamtab, nam)))
 	return 0;
 
     if (pm->level || !(pm->node.flags & PM_AUTOLOAD)) {
@@ -1071,7 +1071,7 @@ addparamdef(Paramdef d)
 	    return 1;
     }
     else if (!(pm = createparam(d->name, d->flags)) &&
-	!(pm = (Param) paramtab->getnode(paramtab, d->name)))
+	!(pm = (Param) realparamtab->getnode2(realparamtab, d->name)))
 	return 1;
 
     d->pm = pm;
@@ -1128,7 +1128,7 @@ addparamdef(Paramdef d)
 int
 deleteparamdef(Paramdef d)
 {
-    Param pm = (Param) paramtab->getnode(paramtab, d->name);
+    Param pm = (Param) realparamtab->getnode2(realparamtab, d->name);
 
     if (!pm)
 	return 1;
@@ -1147,10 +1147,10 @@ deleteparamdef(Paramdef d)
 	if (!searchpm)
 	    return 1;
 
-	paramtab->removenode(paramtab, pm->node.nam);
+	realparamtab->removenode(realparamtab, pm->node.nam);
 	prevpm->old = searchpm->old;
 	searchpm->old = pm;
-	paramtab->addnode(paramtab, searchpm->node.nam, searchpm);
+	realparamtab->addnode(realparamtab, searchpm->node.nam, searchpm);
 
 	pm = searchpm;
     }
@@ -1239,7 +1239,7 @@ add_autoparam(const char *module, const char *pnam, int flags)
 static int
 del_autoparam(UNUSED(const char *modnam), const char *pnam, int flags)
 {
-    Param pm = (Param) gethashnode2(paramtab, pnam);
+    Param pm = (Param) realparamtab->getnode2(realparamtab, pnam);
 
     if (!pm) {
 	if (!(flags & FEAT_IGNORE))
@@ -2760,7 +2760,7 @@ bin_zmodload_auto(char *nam, char **args, Options ops)
     } else if (OPT_ISSET(ops,'p')) {
 	if (!*args) {
 	    /* list autoloaded parameters */
-	    scanhashtable(paramtab, 1, 0, 0, printautoparams,
+	    scanhashtable(realparamtab, 1, 0, 0, printautoparams,
 			  OPT_ISSET(ops,'L'));
 	    return 0;
 	}
diff --git a/Src/params.c b/Src/params.c
index d9722bea2..4f999f518 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -945,7 +945,7 @@ createparamtable(void)
      * For native emulation we always set the variable home
      * (see setupvals()).
      */
-    pm = (Param) paramtab->getnode(paramtab, "HOME");
+    pm = (Param) realparamtab->getnode2(realparamtab, "HOME");
     if (EMULATION(EMULATE_ZSH))
     {
 	pm->node.flags &= ~PM_UNSET;
@@ -953,10 +953,10 @@ createparamtable(void)
 	    addenv(pm, home);
     } else if (!home)
 	pm->node.flags |= PM_UNSET;
-    pm = (Param) paramtab->getnode(paramtab, "LOGNAME");
+    pm = (Param) realparamtab->getnode2(realparamtab, "LOGNAME");
     if (!(pm->node.flags & PM_EXPORTED))
 	addenv(pm, pm->u.str);
-    pm = (Param) paramtab->getnode(paramtab, "SHLVL");
+    pm = (Param) realparamtab->getnode2(realparamtab, "SHLVL");
     sprintf(buf, "%d", (int)++shlvl);
     /* shlvl value in environment needs updating unconditionally */
     addenv(pm, buf);
diff --git a/Src/utils.c b/Src/utils.c
index a1d7c8cc2..f5c51e5df 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -1257,7 +1257,7 @@ getnameddir(char *name)
     /* Check if there is a scalar parameter with this name whose value *
      * begins with a `/'.  If there is, add it to the hash table and   *
      * return the new value.                                           */
-    if ((pm = (Param) paramtab->getnode(paramtab, name)) &&
+    if ((pm = (Param) realparamtab->getnode2(realparamtab, name)) &&
 	    (PM_TYPE(pm->node.flags) == PM_SCALAR) &&
 	    (str = getsparam(name)) && *str == '/') {
 	pm->node.flags |= PM_NAMEDDIR;


Messages sorted by: Reverse Date, Date, Thread, Author