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

compinit (was: Re: #compdef -k menu-select glitch in 3.1.9)



Bart Schaefer wrote:

> ...
> 
> 11440 is the right idea, but I think the test should be for directories
> or files that are writable by anyone other than root or the current user.
> That means files not owned by the root or the current user fail, as do
> files in any group or world writable directory, or in any directory not
> owned by root or by the current user.
> 
> Then it needs three possibilities for how to treat failure of the tests:
> 
> (1) Ask whether to use the completion system.
> (2) Silently ignore all directories and files that fail.
> (3) Silently accept all directories and files in $fpath.

How's the patch below? (Not committed until I get a positive reply.)

It does the tests you mentioned and makes compinit accept three new
options. The patterns used to find `insecure' directories and files
are:

   _i_wdirs=( ${^fpath}(Nf:g+w:,f:o+w:,^u0u${EUID}) )
   _i_wfiles=( ${^~fpath:/.}/^([^_]*|*~|*.zwc)(N^u0u${EUID}) )

The options:

-i: silently ignore `insecure' directories and files
-u: silently use `insecure' directories and files
-C: the same as in 11440, i.e.: make compinit not try to rebuild the
    dumpfile if it exists (small optimisation for people who don't
    fiddle with new completion functions that much)

This means that `ask whether...' is the default, but that's easy to
change, of course.


The patch also contains the test to avoid using the same filename more 
than once and it removes compconf.

Bye
 Sven

diff -u -r ../oz/Completion/Builtins/_pids ./Completion/Builtins/_pids
--- ../oz/Completion/Builtins/_pids	Sat Jun 17 00:08:18 2000
+++ ./Completion/Builtins/_pids	Sat Jun 17 17:32:53 2000
@@ -16,7 +16,7 @@
   match="[[:blank:]]#${PREFIX}[0-9]#${SUFFIX}[[:blank:]]*"
 else
   all=(-U)
-  match="*[[:blank:]]*[/[:blank:]]$PREFIX*$SUFFIX*"
+  match="*[[:blank:]]*[[/[:blank:]]$PREFIX*$SUFFIX*"
   nm="$compstate[nmatches]"
 fi
 
diff -u -r ../oz/Completion/Core/compdump ./Completion/Core/compdump
--- ../oz/Completion/Core/compdump	Sat Jun 17 00:08:20 2000
+++ ./Completion/Core/compdump	Sun Jun 18 12:41:19 2000
@@ -16,13 +16,20 @@
 emulate -L zsh
 setopt extendedglob
 
-typeset _d_file _d_f _d_bks _d_line _d_als
+typeset _d_file _d_f _d_bks _d_line _d_als _d_files
 
 _d_file=${_comp_dumpfile-${0:h}/compinit.dump}.$HOST.$$
 [[ $_d_file = //* ]] && _d_file=${_d_file[2,-1]}
 
-typeset -U _d_files
-_d_files=( ${^~fpath:/.}/^([^_]*|*~|*.zwc)(N:t) )
+_d_files=( ${^~fpath:/.}/^([^_]*|*~|*.zwc)(N) )
+
+if [[ -n "$_comp_secure" ]]; then
+  _d_wdirs=( ${^fpath}(Nf:g+w:,f:o+w:,^u0u${EUID}) )
+  _d_wfiles=( ${^~fpath:/.}/^([^_]*|*~|*.zwc)(N^u0u${EUID}) )
+
+  (( $#_d_wfiles )) && _d_files=( "${(@)_d_files:#(${(j:|:)_d_wfiles})}"  )
+  (( $#_d_wdirs ))  && _d_files=( "${(@)_d_files:#(${(j:|:)_d_wdirs})/*}" )
+fi
 
 print "#files: $#_d_files" > $_d_file
 
diff -u -r ../oz/Completion/Core/compinit ./Completion/Core/compinit
--- ../oz/Completion/Core/compinit	Sat Jun 17 00:08:20 2000
+++ ./Completion/Core/compinit	Sun Jun 18 12:41:41 2000
@@ -61,24 +61,35 @@
 setopt extendedglob
 
 typeset _i_dumpfile _i_files _i_line _i_done _i_dir _i_autodump=1
-typeset _i_tag _i_file _i_addfiles
+typeset _i_tag _i_file _i_addfiles _i_fail=ask _i_check=yes _i_name
 
-while [[ $# -gt 0 && $1 = -[dDf] ]]; do
-  if [[ "$1" = -d ]]; then
+while [[ $# -gt 0 && $1 = -[dDiuc] ]]; do
+  case "$1" in
+  -d)
     _i_autodump=1
     shift
-    if [[ $# -gt 0 && "$1" != -[df] ]]; then
+    if [[ $# -gt 0 && "$1" != -[dfQC] ]]; then
       _i_dumpfile="$1"
       shift
     fi
-  elif [[ "$1" = -D ]]; then
+    ;;
+  -D)
     _i_autodump=0
     shift
-  elif [[ "$1" = -f ]]; then
-    # Not used any more; use _compdir
+    ;;
+  -i)
+    _i_fail=ign
     shift
+    ;;
+  -u)
+    _i_fail=use
     shift
-  fi
+    ;;
+  -C)
+    _i_check=
+    shift
+    ;;
+  esac
 done
 
 # The associative array containing the definitions for the commands.
@@ -303,172 +314,80 @@
   fi
 }
 
-# Do *not* use this...
-
-compconf() {
-
-  local style name val i tmp cmt
-
-  if [[ -z "$_compconf_warn" ]]; then
-    _compconf_warn=yep
-
-    print "
-
-Hello
-
-\`compconf' will be removed in the near future, we now use a more
-general (and powerful) mechanism using the \`zstyle' builtin. An
-approximation to your old setup using \`zstyle' should be available
-in the file:
-
-    \`${HOME}/.zsh-styles'
+# Now we automatically make the definition files autoloaded.
 
-Note that the values for the styles may be partly incorrect. Please
-read the manual to find out how to configure the completion system
-with styles or use the \`compinstall' function.
+typeset _i_wdirs _i_wfiles
 
-Have fun
+_i_wdirs=()
+_i_wfiles=()
 
-   Sven
-" 1>&2
-    command rm -f ${HOME}/.zsh-styles
+if [[ -n "$_i_check" ]]; then
+  _i_files=( ${^~fpath:/.}/^([^_]*|*~|*.zwc)(N) )
+  if [[ $#_i_files -lt 20 || $_compdir = */Core || -d $_compdir/Core ]]; then
+    # Too few files:  we need some more directories,
+    # or we need to check that all directories (not just Core) are present.
+    if [[ -n $_compdir ]]; then
+      _i_addfiles=()
+      if [[ $_compdir = */Core ]]; then
+        # Add all the Completion subdirectories
+        _i_addfiles=(${_compdir:h}/*(/))
+      elif [[ -d $_compdir/Core ]]; then
+        # Likewise
+        _i_addfiles=(${_compdir}/*(/))
+      fi
+      for _i_line in {1..$#i_addfiles}; do
+        _i_file=${_i_addfiles[$_i_line]}
+        [[ -d $_i_file && -z ${fpath[(r)$_i_file]} ]] ||
+          _i_addfiles[$_i_line]=
+      done
+      fpath=($fpath $_i_addfiles)
+      _i_files=( ${^~fpath:/.}/^([^_]*|*~|*.zwc)(N) )
+    fi
   fi
+  if [[ "$_i_fail" != use ]]; then
+    typeset _i_q
 
-  for i; do
-    name="${i%%\=*}"
-    val="${i#*\=}"
-
-    tmp=''
-    cmt=''
-
-    case "$name" in
-    urls_path)
-      tmp="'*:urls' path ${(qq)val}"
-      ;;
-    urls_localhttp)
-      tmp="'*:urls' local ${${(qqs.:.)val}}"
-      ;;
-    describe_options)
-      tmp="'*:options' verbose 'yes'"
-      ;;
-    describe_values)
-      tmp="'*:values' verbose 'yes'"
-      ;;
-    autodescribe_options)
-      tmp="'*:options' auto-description ${(qq)val}"
-      ;;
-    description_format)
-      tmp="'*:descriptions' format ${(qq)val}"
-      ;;
-    message_format)
-      tmp="'*:messages' format ${(qq)val}"
-      ;;
-    warning_format)
-      tmp="'*:warnings' format ${(qq)val}"
-      ;;
-    option_prefix)
-      tmp="'*:options' prefix-needed yes"
-      [[ "$val" = hide* ]] &&
-          tmp="$tmp
-zstyle ':completion:*:options' prefix-hidden yes"
-      ;;    
-    group_matches)
-      tmp="'*' group-name ''"
-      ;;
-    colors_path)
-      tmp="'*:colors' path ${(qq)val}"
-      ;;
-    path_expand)
-      tmp="'*:paths' expand ${(qq)val}"
-      ;;
-    path_cursor)
-      tmp="'*:paths' cursor ${(qq)val}"
-      ;;
-    (approximate|incremental|predict|list|oldlist|match)_*)
-      tmp="'*${name%%_*}:*' ${${name#*_}//_/-} ${(qq)val}"
-      ;;
-    correct_*)
-      cmt="# This one is a bit ugly. You may want to use only \`*:correct'
-# if you also have the \`correctword_*' or \`approximate_*' keys.
-"
-      tmp="'*(correct(|-word)|approximate):*' ${name#*_} ${(qq)val}"
-      ;;
-    correctword_*)
-      tmp="'*:correct-word' ${name#correctword_} ${(qq)val}"
-      ;;
-    expand_*)
-      cmt="# This one is a bit ugly. You may want to use only \`*:expand'
-# if you also have the \`expandword_*' keys.
-"
-      tmp="'*expand(|expand-word):*' ${name#*_} ${(qq)val}"
-      ;;
-    expandword_*)
-      tmp="'expand-word:*' ${name#expandword_} ${(qq)val}"
-      ;;
-    history_*)
-      tmp="'history-words:*' ${name#history_} ${(qq)val}"
-      ;;
-    completer)
-      tmp="'*' completer ${${(qqs.:.)val}}"
-      ;;
-    last_prompt)
-      tmp="'*' last-prompt 'yes'"
-      ;;
-    esac
-    [[ -n "$tmp" ]] && style="${style}${cmt}zstyle :completion:${tmp}
-"
-  done
+    _i_wdirs=( ${^fpath}(Nf:g+w:,f:o+w:,^u0u${EUID}) )
+    _i_wfiles=( ${^~fpath:/.}/^([^_]*|*~|*.zwc)(N^u0u${EUID}) )
 
-  eval "${style}"
-
-  print "$style" >>! ${HOME}/.zsh-styles
-}
+    case "${#_i_wdirs}:${#_i_wfiles}" in
+    0:0) _i_q= ;;
+    0:*) _i_q=files ;;
+    *:0) _i_q=directories ;;
+    *:*) _i_q='directories and files' ;;
+    esac
 
-# Now we automatically make the definition files autoloaded.
+    if [[ -n "$_i_q" ]]; then
+      if [[ "$_i_fail" = ask ]] &&
+         ! read -q "?There are insecure $_i_q, continue [yn]? "; then
+        unfunction compinit compdef
+        unset _comp_dumpfile _comp_secure compprefuncs comppostfuncs \
+              _comps _patcomps _postpatcomps _compautos _lastcomp
 
-typeset -U _i_files
-_i_files=( ${^~fpath:/.}/^([^_]*|*~|*.zwc)(N:t) )
-if [[ $#_i_files -lt 20 || $_compdir = */Core || -d $_compdir/Core ]]; then
-  # Too few files:  we need some more directories,
-  # or we need to check that all directories (not just Core) are present.
-  if [[ -n $_compdir ]]; then
-    _i_addfiles=()
-    if [[ $_compdir = */Core ]]; then
-      # Add all the Completion subdirectories
-      _i_addfiles=(${_compdir:h}/*(/))
-    elif [[ -d $_compdir/Core ]]; then
-      # Likewise
-      _i_addfiles=(${_compdir}/*(/))
+        return 1
+      fi
+      (( $#_i_wfiles )) && _i_files=( "${(@)_i_files:#(${(j:|:)_i_wfiles})}"  )
+      (( $#_i_wdirs ))  && _i_files=( "${(@)_i_files:#(${(j:|:)_i_wdirs})/*}" )
     fi
-    for _i_line in {1..$#i_addfiles}; do
-      _i_file=${_i_addfiles[$_i_line]}
-      [[ -d $_i_file && -z ${fpath[(r)$_i_file]} ]] ||
-        _i_addfiles[$_i_line]=
-    done
-    fpath=($fpath $_i_addfiles)
-    _i_files=( ${^~fpath:/.}/^([^_]*|*~|*.zwc)(N:t) )
+    _comp_secure=yes
   fi
 fi
 
-
-# Rebind the standard widgets
-for _i_line in complete-word delete-char-or-list expand-or-complete \
-  expand-or-complete-prefix list-choices menu-complete \
-  menu-expand-or-complete reverse-menu-complete; do
-  zle -C $_i_line .$_i_line _main_complete
-done
-zle -la menu-select && zle -C menu-select .menu-select _main_complete
-
-_i_done=''
-
 # Make sure compdump is available, even if we aren't going to use it.
 autoload -U compdump compinstall
 
 # If we have a dump file, load it.
 
+_i_done=''
+
 if [[ -f "$_comp_dumpfile" ]]; then
-  read -rA _i_line < "$_comp_dumpfile"
-  if [[ _i_autodump -eq 1 && $_i_line[2] -eq $#_i_files ]]; then
+  if [[ -n "$_i_check" ]]; then
+    read -rA _i_line < "$_comp_dumpfile"
+    if [[ _i_autodump -eq 1 && $_i_line[2] -eq $#_i_files ]]; then
+      builtin . "$_comp_dumpfile"
+      _i_done=yes
+    fi
+  else
     builtin . "$_comp_dumpfile"
     _i_done=yes
   fi
@@ -476,21 +395,24 @@
 if [[ -z "$_i_done" ]]; then
   for _i_dir in $fpath; do
     [[ $_i_dir = . ]] && continue
+    (( $_i_wdirs[(I)$_i_dir] )) && continue
     for _i_file in $_i_dir/^([^_]*|*~|*.zwc)(N); do
+      _i_name="${_i_file:t}"
+      (( $+functions[$_i_name] + $_i_wfiles[(I)$_i_file] )) && continue
       read -rA _i_line < $_i_file
       _i_tag=$_i_line[1]
       shift _i_line
       case $_i_tag in
       (\#compdef)
 	if [[ $_i_line[1] = -[pPkK](n|) ]]; then
-	  compdef ${_i_line[1]}na "${_i_file:t}" "${(@)_i_line[2,-1]}"
+	  compdef ${_i_line[1]}na "${_i_name}" "${(@)_i_line[2,-1]}"
 	else
-	  compdef -na "${_i_file:t}" "${_i_line[@]}"
+	  compdef -na "${_i_name}" "${_i_line[@]}"
 	fi
 	;;
       (\#autoload)
-	autoload -U "$_i_line[@]" ${_i_file:t}
-	[[ "$_i_line" != \ # ]] && _compautos[${_i_file:t}]="$_i_line"
+	autoload -U "$_i_line[@]" ${_i_name}
+	[[ "$_i_line" != \ # ]] && _compautos[${_i_name}]="$_i_line"
 	;;
       esac
     done
@@ -503,5 +425,15 @@
   fi
 fi
 
+# Rebind the standard widgets
+for _i_line in complete-word delete-char-or-list expand-or-complete \
+  expand-or-complete-prefix list-choices menu-complete \
+  menu-expand-or-complete reverse-menu-complete; do
+  zle -C $_i_line .$_i_line _main_complete
+done
+zle -la menu-select && zle -C menu-select .menu-select _main_complete
+
 unfunction compinit
 autoload -U compinit
+
+return 0
diff -u -r ../oz/Doc/Zsh/compsys.yo ./Doc/Zsh/compsys.yo
--- ../oz/Doc/Zsh/compsys.yo	Sat Jun 17 00:08:12 2000
+++ ./Doc/Zsh/compsys.yo	Sun Jun 18 12:51:14 2000
@@ -92,7 +92,10 @@
 and produce a new dump file.  However, if the name of a function or the
 arguments in the first line of a tt(#compdef) function (as described below)
 change, it is easiest to delete the dump file by hand so that
-tt(compinit) will re-create it the next time it is run.
+tt(compinit) will re-create it the next time it is run.  The check
+performed to see if there are new functions can be omitted by giving
+the option tt(-C).  In this case the dump file will only be created if
+there isn't one already.
 
 The dumping is actually done by another function, tt(compdump), but you
 will only need to run this yourself if you change the configuration
@@ -102,6 +105,16 @@
 If the parameter tt(_compdir) is set, tt(compinit) uses it as a directory
 where completion functions can be found; this is only necessary if they are
 not already in the function search path.
+
+For security reasons tt(compinit) also checks if the completion system
+would use files not owned by root or the current user or files in
+directories that are world- or group-writable or that are not owned by 
+root or the current user.  If such files or directories are found,
+tt(Compinit) will ask if the completion system should really be used.
+To avoid these tests and make all files found be used without asking,
+the option tt(-u) can be given and to make tt(compinit) silently
+ignore all insecure files and directories the options tt(-i) can be
+given.
 
 subsect(Autoloaded files)
 cindex(completion system, autoloaded functions)

--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



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