56cdec75348cc7c33f54c5441884238c25a6597b

Author
Robby Russell <robby@planetargon.com>
Committer
Robby Russell <robby@planetargon.com>
Date

Message

Merge pull request #3889 from leycec/compaudit

Repair `zsh` Path Permissions on `oh-my-zsh` Startup under Cygwin

Diff

  1diff --git a/lib/compfix.zsh b/lib/compfix.zsh
  2new file mode 100644
  3index 0000000000000000000000000000000000000000..208aaadb1ebad0e25ebdef29192da815be8136bd
  4--- /dev/null
  5+++ b/lib/compfix.zsh
  6@@ -0,0 +1,60 @@
  7+# Handle completions insecurities (i.e., completion-dependent directories with
  8+# insecure ownership or permissions) by:
  9+#
 10+# * Human-readably notifying the user of these insecurities.
 11+# * Moving away all existing completion caches to a temporary directory. Since
 12+#   any of these caches may have been generated from insecure directories, they
 13+#   are all suspect now. Failing to do so typically causes subsequent compinit()
 14+#   calls to fail with "command not found: compdef" errors. (That's bad.)
 15+function handle_completion_insecurities() {
 16+  # List of the absolute paths of all unique insecure directories, split on
 17+  # newline from compaudit()'s output resembling:
 18+  #
 19+  #     There are insecure directories:
 20+  #     /usr/share/zsh/site-functions
 21+  #     /usr/share/zsh/5.0.6/functions
 22+  #     /usr/share/zsh
 23+  #     /usr/share/zsh/5.0.6
 24+  #
 25+  # Since the ignorable first line is printed to stderr and thus not captured,
 26+  # stderr is squelched to prevent this output from leaking to the user. 
 27+  local -aU insecure_dirs
 28+  insecure_dirs=( ${(f@):-"$(compaudit 2>/dev/null)"} )
 29+
 30+  # If no such directories exist, get us out of here.
 31+  if (( ! ${#insecure_dirs} )); then
 32+      print "[oh-my-zsh] No insecure completion-dependent directories detected."
 33+      return
 34+  fi
 35+
 36+  # List ownership and permissions of all insecure directories.
 37+  print "[oh-my-zsh] Insecure completion-dependent directories detected:"
 38+  ls -ld "${(@)insecure_dirs}"
 39+  print "[oh-my-zsh] For safety, completions will be disabled until you manually fix all"
 40+  print "[oh-my-zsh] insecure directory permissions and ownership and restart oh-my-zsh."
 41+  print "[oh-my-zsh] See the above list for directories with group or other writability.\n"
 42+
 43+  # Locally enable the "NULL_GLOB" option, thus removing unmatched filename
 44+  # globs from argument lists *AND* printing no warning when doing so. Failing
 45+  # to do so prints an unreadable warning if no completion caches exist below.
 46+  setopt local_options null_glob
 47+
 48+  # List of the absolute paths of all unique existing completion caches.
 49+  local -aU zcompdump_files
 50+  zcompdump_files=( "${ZSH_COMPDUMP}"(.) "${ZDOTDIR:-${HOME}}"/.zcompdump* )
 51+
 52+  # Move such caches to a temporary directory.
 53+  if (( ${#zcompdump_files} )); then
 54+    # Absolute path of the directory to which such files will be moved.
 55+    local ZSH_ZCOMPDUMP_BAD_DIR="${ZSH_CACHE_DIR}/zcompdump-bad"
 56+
 57+    # List such files first.
 58+    print "[oh-my-zsh] Insecure completion caches also detected:"
 59+    ls -l "${(@)zcompdump_files}"
 60+
 61+    # For safety, move rather than permanently remove such files.
 62+    print "[oh-my-zsh] Moving to \"${ZSH_ZCOMPDUMP_BAD_DIR}/\"...\n"
 63+    mkdir -p "${ZSH_ZCOMPDUMP_BAD_DIR}"
 64+    mv "${(@)zcompdump_files}" "${ZSH_ZCOMPDUMP_BAD_DIR}/"
 65+  fi
 66+}
 67diff --git a/oh-my-zsh.sh b/oh-my-zsh.sh
 68index 4e5f77990dd567ca1495ed2af948473609ed1bfe..8e31ddd0ff62c43d187cd6f6fd2bf97a72a0bc11 100644
 69--- a/oh-my-zsh.sh
 70+++ b/oh-my-zsh.sh
 71@@ -8,6 +8,9 @@ fi
 72 # add a function path
 73 fpath=($ZSH/functions $ZSH/completions $fpath)
 74 
 75+# Load all stock functions (from $fpath files) called below.
 76+autoload -U compaudit compinit
 77+
 78 # Set ZSH_CUSTOM to the path where your custom config files
 79 # and plugins exists, or else we will use the default custom/
 80 if [[ -z "$ZSH_CUSTOM" ]]; then
 81@@ -59,9 +62,14 @@ if [ -z "$ZSH_COMPDUMP" ]; then
 82   ZSH_COMPDUMP="${ZDOTDIR:-${HOME}}/.zcompdump-${SHORT_HOST}-${ZSH_VERSION}"
 83 fi
 84 
 85-# Load and run compinit
 86-autoload -U compinit
 87-compinit -i -d "${ZSH_COMPDUMP}"
 88+# If completion insecurities exist, warn the user without enabling completions.
 89+if ! compaudit &>/dev/null; then
 90+  # This function resides in the "lib/compfix.zsh" script sourced above.
 91+  handle_completion_insecurities
 92+# Else, enable and cache completions to the desired file.
 93+else
 94+  compinit -d "${ZSH_COMPDUMP}"
 95+fi
 96 
 97 # Load all of the plugins that were defined in ~/.zshrc
 98 for plugin ($plugins); do
 99diff --git a/tools/install.sh b/tools/install.sh
100index 1586cdee567d12e0d501566e027f51c7b797dcc5..aebd2837175a610e1876ddd473219b131528f1c7 100755
101--- a/tools/install.sh
102+++ b/tools/install.sh
103@@ -16,6 +16,13 @@ if [ -d "$ZSH" ]; then
104   exit
105 fi
106 
107+# Prevent the cloned repository from having insecure permissions. Failing to do
108+# so causes compinit() calls to fail with "command not found: compdef" errors
109+# for users with insecure umasks (e.g., "002", allowing group writability). Note
110+# that this will be ignored under Cygwin by default, as Windows ACLs take
111+# precedence over umasks except for filesystems mounted with option "noacl".
112+umask g-w,o-w
113+
114 echo "\033[0;34mCloning Oh My Zsh...\033[0m"
115 hash git >/dev/null 2>&1 && env git clone --depth=1 https://github.com/robbyrussell/oh-my-zsh.git $ZSH || {
116   echo "git not installed"
117@@ -41,12 +48,17 @@ export PATH=\"$PATH\"
118 " ~/.zshrc > ~/.zshrc-omztemp
119 mv -f ~/.zshrc-omztemp ~/.zshrc
120 
121-TEST_CURRENT_SHELL=$(expr "$SHELL" : '.*/\(.*\)')
122-if [ "$TEST_CURRENT_SHELL" != "zsh" ]; then
123+# If this user's login shell is not already "zsh", attempt to switch.
124+if [ "$(expr "$SHELL" : '.*/\(.*\)')" != "zsh" ]; then
125+  # If this platform provides a "chsh" command (not Cygwin), do it, man!
126+  if hash chsh >/dev/null 2>&1; then
127     echo "\033[0;34mTime to change your default shell to zsh!\033[0m"
128     chsh -s $(grep /zsh$ /etc/shells | tail -1)
129+  # Else, suggest the user do so manually.
130+  else
131+    echo "\033[0;34mPlease manually change your default shell to zsh!\033[0m"
132+  fi
133 fi
134-unset TEST_CURRENT_SHELL
135 
136 echo "\033[0;32m"'         __                                     __   '"\033[0m"
137 echo "\033[0;32m"'  ____  / /_     ____ ___  __  __   ____  _____/ /_  '"\033[0m"