From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1617 invoked from network); 20 Jun 2000 07:13:47 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 20 Jun 2000 07:13:47 -0000 Received: (qmail 12620 invoked by alias); 20 Jun 2000 07:13:33 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 11998 Received: (qmail 12613 invoked from network); 20 Jun 2000 07:13:32 -0000 Date: Tue, 20 Jun 2000 09:13:30 +0200 (MET DST) Message-Id: <200006200713.JAA32600@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@sunsite.auc.dk In-reply-to: "Bart Schaefer"'s message of Mon, 19 Jun 2000 18:37:06 +0000 Subject: PATCH: Re: compinit (was: Re: #compdef -k menu-select glitch in 3.1.9) Bart Schaefer wrote: > On Jun 19, 12:36pm, Sven Wischnowsky wrote: > } Subject: compinit (was: Re: #compdef -k menu-select glitch in 3.1.9) > > ... > > } > } _i_wdirs=( ${^fpath}(Nf:g+w:,f:o+w:,^u0u${EUID}) ) > } _i_wfiles=( ${^~fpath:/.}/^([^_]*|*~|*.zwc)(N^u0u${EUID}) ) > > Argh. The one problem with this is RedHat linux's penchant for creating > groups that contain exactly one user. So it's actually safe to have a > group writable directory on RedHat as long as the name of the group is > the same as the name of the user. This has caused problems for some > other security-conscious packages as well, notably procmail. > > I think you should commit the patch as is, and I'll think some more about > the right way to address this. It might have to be a configure-time thing. Good. > } 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. > > No, I think that's fine. NOTE to everyone: This means that to get the same behaviour as before, compinit has to be called with the -u option (if you don't care about security or don't have to care about it). > } The patch also contains the test to avoid using the same filename more > } than once and it removes compconf. > > If the former means what I think it means, then thanks very much. Yes, I meant that ;-) ( the (( $+functions[${_i_file:t}] )) && continue Bye Sven Index: Completion/Builtins/_pids =================================================================== RCS file: /cvsroot/zsh/zsh/Completion/Builtins/_pids,v retrieving revision 1.5 diff -u -r1.5 _pids --- Completion/Builtins/_pids 2000/05/08 08:16:32 1.5 +++ Completion/Builtins/_pids 2000/06/20 07:07:44 @@ -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 Index: Completion/Core/compdump =================================================================== RCS file: /cvsroot/zsh/zsh/Completion/Core/compdump,v retrieving revision 1.5 diff -u -r1.5 compdump --- Completion/Core/compdump 2000/05/31 09:23:28 1.5 +++ Completion/Core/compdump 2000/06/20 07:07:44 @@ -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 Index: Completion/Core/compinit =================================================================== RCS file: /cvsroot/zsh/zsh/Completion/Core/compinit,v retrieving revision 1.4 diff -u -r1.4 compinit --- Completion/Core/compinit 2000/05/31 09:23:28 1.4 +++ Completion/Core/compinit 2000/06/20 07:07:44 @@ -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. @@ -302,173 +313,81 @@ esac 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 Index: Doc/Zsh/compsys.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/compsys.yo,v retrieving revision 1.71 diff -u -r1.71 compsys.yo --- Doc/Zsh/compsys.yo 2000/06/19 13:09:07 1.71 +++ Doc/Zsh/compsys.yo 2000/06/20 07:07:45 @@ -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@informatik.hu-berlin.de