summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikael Magnusson <mikachu@gmail.com>2026-05-26 17:24:40 +0200
committerMikael Magnusson <mikachu@gmail.com>2026-06-04 05:45:50 +0200
commit0883f8fec6d08780229f239ce0c3455efe19a198 (patch)
tree9b8cfd2c766d6147da2cf183e735a8d2ec4412c4
parentunposted: remove further remnant of restricted mode (diff)
downloadzsh-0883f8fec6d08780229f239ce0c3455efe19a198.tar
zsh-0883f8fec6d08780229f239ce0c3455efe19a198.tar.gz
zsh-0883f8fec6d08780229f239ce0c3455efe19a198.tar.bz2
zsh-0883f8fec6d08780229f239ce0c3455efe19a198.tar.lz
zsh-0883f8fec6d08780229f239ce0c3455efe19a198.tar.xz
zsh-0883f8fec6d08780229f239ce0c3455efe19a198.tar.zst
zsh-0883f8fec6d08780229f239ce0c3455efe19a198.zip
54617: fix lookup in $commands array when hashlistall is unset
While the documentation for the zsh/parameter module does state The zsh/parameter module gives access to some of the internal hash tables and commands This array gives access to the command hash table. , the latter entry does *also* say values are the pathnames of the files that would be executed when the command would be invoked. Change getpmcommand to always do a lookup via findcmd() if it the entry is not found in the hash and HASHLISTALL is unset. This will indirectly respect HASHCMDS and add the single entry if it is set, look it up in the hash if it was added and then HASHCMDS was unset, etc.
-rw-r--r--ChangeLog6
-rw-r--r--Src/Modules/parameter.c18
-rw-r--r--Src/zsh.h4
-rw-r--r--Test/V06parameter.ztst19
4 files changed, 41 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 6845b31a5..105dd0a6c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-06-04 Mikael Magnusson <mikachu@gmail.com>
+
+ * 54617: Src/Modules/parameter.c, Src/zsh.h,
+ Test/V06parameter.ztst: fix lookup in $commands array when
+ hashlistall is unset
+
2026-06-04 Oliver Kiddle <opk@zsh.org>
* unposted: Src/zsh.h: remove further remnant of restricted mode
diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index 6d1f74d22..2bcfe81a3 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -217,10 +217,20 @@ getpmcommand(UNUSED(HashTable ht), const char *name)
Cmdnam cmd;
Param pm = NULL;
- if (!(cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name)) &&
- isset(HASHLISTALL)) {
- cmdnamtab->filltable(cmdnamtab);
- cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name);
+ if (!(cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name))) {
+ if (isset(HASHLISTALL)) {
+ cmdnamtab->filltable(cmdnamtab);
+ cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name);
+ } else {
+ /* this will return the path even if hashcmds is disabled,
+ * and store it in the hash if it is enabled */
+ char *found = findcmd((char*)name, 1, 0);
+ if (found) {
+ cmd = (Cmdnam) hcalloc(sizeof(*cmd));
+ cmd->u.cmd = found;
+ cmd->node.flags = HASHED;
+ }
+ }
}
pm = (Param) hcalloc(sizeof(struct param));
pm->node.nam = dupstring(name);
diff --git a/Src/zsh.h b/Src/zsh.h
index 83a92e8d6..2858b46aa 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1301,8 +1301,8 @@ enum {
struct cmdnam {
struct hashnode node;
union {
- char **name; /* full pathname for external commands */
- char *cmd; /* file name for hashed commands */
+ char **name; /* pointer into path array for external commands */
+ char *cmd; /* file name for hashed commands */
}
u;
};
diff --git a/Test/V06parameter.ztst b/Test/V06parameter.ztst
index 27d587852..c1f47a9dc 100644
--- a/Test/V06parameter.ztst
+++ b/Test/V06parameter.ztst
@@ -92,6 +92,25 @@
>foo
>bar
+ for 1 in hash_cmds no_hash_cmds; do
+ (
+ setopt no_hash_list_all $1
+ : > ls
+ chmod +x ls
+ rm=$commands[rm]
+ path=( $PWD )
+ rehash
+ a=$commands[ls]
+ $rm ls
+ b=$commands[ls]
+ [[ $a == $b ]]
+ print -r - $? $a:$b
+ )
+ done
+-:workers/54617: $commands look-up with no_hash_list_all
+*>0 */ls:*/ls
+*>1 */ls:
+
%clean
rm -f autofn functrace.zsh rocky3.zsh sourcedfile myfunc