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

[PATCH] compaudit: avoid defining a global getent fallback



Hello,

On systems without an external getent command, compaudit defines a global getent fallback function. This function remains after compaudit returns and overwrites any existing user-defined function of the same name.

The fallback behaves quite differently from a regular getent command. It only searches files under /etc using grep and sed, rather than querying the system's name services. For example, getent hosts does not perform DNS lookups, and getent passwd 0 does not look up a user by UID. Users may mistake it for a regular getent command and be misled by empty or incomplete results. I noticed this through `which getent` on macOS, which does not ship with getent.

The attached patch removes the global fallback function and inlines the group lookup fallback where compaudit needs it. This preserves the existing group lookup behavior without introducing or overwriting a getent function in the calling shell.

Verified on macOS using zsh built from commit 7e57394:
- All seven existing completion test scripts pass.
- Completion initialization succeeds without defining a global getent function.

Thank you,
Xichen Zeng
From bf83a2f7b0697ce186b48c5c2a334d57ea521063 Mon Sep 17 00:00:00 2001
From: Xichen Z <xichenzr@xxxxxxxxx>
Date: Sat, 31 Oct 2026 10:41:10 +0800
Subject: [PATCH] compaudit: avoid defining a global getent fallback

When no external getent command is available, compaudit defines a
global getent function. This function remains after compaudit returns
and overwrites an existing user-defined getent function.

Inline the group lookup fallback at its call site instead, preserving
the existing fallback behavior without defining a global function.
---
 Completion/compaudit | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/Completion/compaudit b/Completion/compaudit
index 93a043124..ce7927634 100644
--- a/Completion/compaudit
+++ b/Completion/compaudit
@@ -15,16 +15,6 @@ compaudit() {                           # Define and then call
 emulate -L zsh
 setopt extendedglob
 
-[[ -n $commands[getent] ]] || getent() {
-  if [[ $1 = hosts ]]; then
-    sed 's/#.*//' /etc/$1 | grep -w $2
-  elif [[ $2 = <-> ]]; then
-    grep ":$2:[^:]*$" /etc/$1
-  else
-    grep "^$2:" /etc/$1
-  fi
-}
-
 # The positional parameters are the directories to check, else fpath.
 if (( $# )); then
   local _compdir=''
@@ -132,12 +122,19 @@ _i_wdirs=( ${^fpath}(N-f:g+w:,-f:o+w:,-^${_i_owners})
 # that this has not happened, and pick the best group.
 
 if (( $#_i_wdirs )); then
-  local GROUP GROUPMEM _i_pw _i_gid
+  local GROUP GROUPMEM _i_pw _i_gid _i_group
   if ((UID == EUID )); then
-    getent group $LOGNAME | IFS=: read GROUP _i_pw _i_gid GROUPMEM
+    _i_group=$LOGNAME
   else
-    getent group $EGID | IFS=: read GROUP _i_pw _i_gid GROUPMEM
+    _i_group=$EGID
   fi
+  if [[ -n $commands[getent] ]]; then
+    getent group "$_i_group"
+  elif [[ $_i_group = <-> ]]; then
+    grep ":$_i_group:[^:]*$" /etc/group
+  else
+    grep "^$_i_group:" /etc/group
+  fi | IFS=: read GROUP _i_pw _i_gid GROUPMEM
 
   if [[ $GROUP == $LOGNAME && ( -z $GROUPMEM || $GROUPMEM == $LOGNAME ) ]]
   then
-- 
2.55.0



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