Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
[PATCH] Don't perform dereferencing when looking up certain special parameters
- X-seq: zsh-workers 54475
- From: Philippe Altherr <philippe.altherr@xxxxxxxxx>
- To: Zsh hackers list <zsh-workers@xxxxxxx>
- Subject: [PATCH] Don't perform dereferencing when looking up certain special parameters
- Date: Wed, 6 May 2026 01:07:42 +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-20240605; h=to:subject:message-id:date:from:mime-version:dkim-signature; bh=cwGj5KS40/tkw/gja3sBkYI3bwEhQQGvmOKKyAzN6vU=; fh=BgAYDYpL6Ne/A5nWEMVJiHiBtrz8Imz3uf26RDwgQX4=; b=HvX/Qh+EsHKGDD+NPdGdYc5oOcU1Cl2OIZ97oM7ogyYM9s41RCRQPKNUINF0eI3xAW VsZr6iOtfhL8lt1UUKIahndtkhPIx5+BvDSSYA1kbQd+jHWnrFj+X0mS668UYm/3bSq2 2Xz6X8h7kSbf58aMEeKmLsvMo5tred8eGTurqlgfJRg+VEZZR+dw7/68WH/8j7O1jeWi DBOkpPxag94a9NhBc5j2M29u3IQFwTIOMMRDXPsW267i2UjPayKxuIhMjJ1YRzPSFGds jIzYNXhjgvJNDBAp4CzhqwoJXP4eLM6w8YrfTx1VWjxdIlXPTIi0HG6znnS1dOI0l1ZN jfhA==; darn=zsh.org
- Arc-seal: i=1; a=rsa-sha256; t=1778022474; cv=none; d=google.com; s=arc-20240605; b=Xu/Opc5Yq8prz+TZP7ac81K3wtEF0cVKJKya5XS2Dlz2fBUZypHHYnP5xHc0oMHCKz t35ZblxZvbOrY5/XGRBdnnSS5B8lZvxPuPXTQQOPUtWo193Z/ktPK/4jBNhFWK5wqKhz gH/ANDILJIO/cUprddpq3199h3fqIaaBX2TPRW48IyOPlmStOfs/P86dCLWzXBH8IfiF L7KVTtPE/R/FBuQHMXPb31Nl9b5xHbpJpAf2Y2roGgsOXJ57p7c6IRNEYGy5qk/XTJGE nvK6e764lzPBrO5K88YGVkkuJsJRk7716gYmtM+eWoQJqW16FPgFwYjlKECIWkgkNbUt 730Q==
- Archived-at: <https://zsh.org/workers/54475>
- List-id: <zsh-workers.zsh.org>
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.
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