From 304af0a577336abd3090f9dec645052c4c987a47 Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Wed, 15 Dec 2021 13:03:16 +0100 Subject: fix(lib): quote % in `git_remote_status` --- lib/git.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/git.zsh b/lib/git.zsh index 62aac8f39..be9fa7e67 100644 --- a/lib/git.zsh +++ b/lib/git.zsh @@ -82,7 +82,7 @@ function git_remote_status() { fi if [[ -n $ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_DETAILED ]]; then - git_remote_status="$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_PREFIX$remote$git_remote_status_detailed$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_SUFFIX" + git_remote_status="$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_PREFIX${remote:gs/%/%%}$git_remote_status_detailed$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_SUFFIX" fi echo $git_remote_status -- cgit v1.2.3-70-g09d2 From 5b076eab9bf8b85b48faac20383aa20ba0f8b740 Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Sun, 26 Dec 2021 19:31:07 +0100 Subject: fix(lib): quote % in `nvm_prompt_info` --- lib/nvm.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/nvm.zsh b/lib/nvm.zsh index 2fe57a8f4..a8989f9fe 100644 --- a/lib/nvm.zsh +++ b/lib/nvm.zsh @@ -2,5 +2,5 @@ function nvm_prompt_info() { which nvm &>/dev/null || return local nvm_prompt=${$(nvm current)#v} - echo "${ZSH_THEME_NVM_PROMPT_PREFIX}${nvm_prompt}${ZSH_THEME_NVM_PROMPT_SUFFIX}" + echo "${ZSH_THEME_NVM_PROMPT_PREFIX}${nvm_prompt:gs/%/%%}${ZSH_THEME_NVM_PROMPT_SUFFIX}" } -- cgit v1.2.3-70-g09d2 From a92ee838f3e6b1a8dba548673555ebd514939324 Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Sun, 9 Jan 2022 20:27:22 +0100 Subject: fix(cli): follow symlinks in plugin or theme completions --- lib/cli.zsh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/cli.zsh b/lib/cli.zsh index 8cf8368e6..0a85402df 100644 --- a/lib/cli.zsh +++ b/lib/cli.zsh @@ -61,7 +61,7 @@ function _omz { # if command is "disable", only offer already enabled plugins valid_plugins=($plugins) else - valid_plugins=("$ZSH"/plugins/*/{_*,*.plugin.zsh}(.N:h:t) "$ZSH_CUSTOM"/plugins/*/{_*,*.plugin.zsh}(.N:h:t)) + valid_plugins=("$ZSH"/plugins/*/{_*,*.plugin.zsh}(-.N:h:t) "$ZSH_CUSTOM"/plugins/*/{_*,*.plugin.zsh}(-.N:h:t)) # if command is "enable", remove already enabled plugins [[ "${words[3]}" = enable ]] && valid_plugins=(${valid_plugins:|plugins}) fi @@ -69,11 +69,11 @@ function _omz { _describe 'plugin' valid_plugins ;; plugin::info) local -aU plugins - plugins=("$ZSH"/plugins/*/{_*,*.plugin.zsh}(.N:h:t) "$ZSH_CUSTOM"/plugins/*/{_*,*.plugin.zsh}(.N:h:t)) + plugins=("$ZSH"/plugins/*/{_*,*.plugin.zsh}(-.N:h:t) "$ZSH_CUSTOM"/plugins/*/{_*,*.plugin.zsh}(-.N:h:t)) _describe 'plugin' plugins ;; theme::(set|use)) local -aU themes - themes=("$ZSH"/themes/*.zsh-theme(.N:t:r) "$ZSH_CUSTOM"/**/*.zsh-theme(.N:r:gs:"$ZSH_CUSTOM"/themes/:::gs:"$ZSH_CUSTOM"/:::)) + themes=("$ZSH"/themes/*.zsh-theme(-.N:t:r) "$ZSH_CUSTOM"/**/*.zsh-theme(-.N:r:gs:"$ZSH_CUSTOM"/themes/:::gs:"$ZSH_CUSTOM"/:::)) _describe 'theme' themes ;; esac elif (( CURRENT > 4 )); then @@ -85,7 +85,7 @@ function _omz { # if command is "disable", only offer already enabled plugins valid_plugins=($plugins) else - valid_plugins=("$ZSH"/plugins/*/{_*,*.plugin.zsh}(.N:h:t) "$ZSH_CUSTOM"/plugins/*/{_*,*.plugin.zsh}(.N:h:t)) + valid_plugins=("$ZSH"/plugins/*/{_*,*.plugin.zsh}(-.N:h:t) "$ZSH_CUSTOM"/plugins/*/{_*,*.plugin.zsh}(-.N:h:t)) # if command is "enable", remove already enabled plugins [[ "${words[3]}" = enable ]] && valid_plugins=(${valid_plugins:|plugins}) fi -- cgit v1.2.3-70-g09d2 From 035c856c2cbbad2b45252ec8c065c3a9e7eefa65 Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Thu, 13 Jan 2022 17:46:09 +0100 Subject: fix: get branch name first in `omz version` and changelog --- lib/cli.zsh | 7 ++++--- tools/changelog.sh | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/cli.zsh b/lib/cli.zsh index 0a85402df..ec59d1d44 100644 --- a/lib/cli.zsh +++ b/lib/cli.zsh @@ -791,12 +791,13 @@ function _omz::version { # Get the version name: # 1) try tag-like version - # 2) try name-rev - # 3) try branch name + # 2) try branch name + # 3) try name-rev (tag~ or branch~) local version version=$(command git describe --tags HEAD 2>/dev/null) \ + || version=$(command git symbolic-ref --quiet --short HEAD 2>/dev/null) \ || version=$(command git name-rev --no-undefined --name-only --exclude="remotes/*" HEAD 2>/dev/null) \ - || version=$(command git symbolic-ref --quiet --short HEAD 2>/dev/null) + || version="" # Get short hash for the current HEAD local commit=$(command git rev-parse --short HEAD 2>/dev/null) diff --git a/tools/changelog.sh b/tools/changelog.sh index 86774a7ea..49532a4a4 100755 --- a/tools/changelog.sh +++ b/tools/changelog.sh @@ -395,12 +395,12 @@ function main { # Get the first version name: # 1) try tag-like version, or - # 2) try name-rev, or - # 3) try branch name, or + # 2) try branch name, or + # 3) try name-rev, or # 4) try short hash version=$(command git describe --tags $until 2>/dev/null) \ - || version=$(command git name-rev --no-undefined --name-only --exclude="remotes/*" $until 2>/dev/null) \ || version=$(command git symbolic-ref --quiet --short $until 2>/dev/null) \ + || version=$(command git name-rev --no-undefined --name-only --exclude="remotes/*" $until 2>/dev/null) \ || version=$(command git rev-parse --short $until 2>/dev/null) # Get commit list from $until commit until $since commit, or until root commit if $since is unset -- cgit v1.2.3-70-g09d2 From 567bd593954641bd59376f6fd5f9c06bf37bc9e7 Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Mon, 17 Jan 2022 13:18:10 +0100 Subject: refactor(cli): use self-referencing in subcommand functions --- lib/cli.zsh | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'lib') diff --git a/lib/cli.zsh b/lib/cli.zsh index ec59d1d44..70076bcfb 100644 --- a/lib/cli.zsh +++ b/lib/cli.zsh @@ -182,7 +182,7 @@ function _omz::changelog { ! command git rev-parse --verify "${version}^{commit}" ) &>/dev/null; then cat >&2 < must be a valid branch, tag or commit. EOF @@ -193,9 +193,9 @@ EOF } function _omz::plugin { - (( $# > 0 && $+functions[_omz::plugin::$1] )) || { + (( $# > 0 && $+functions[$0::$1] )) || { cat >&2 < [options] +Usage: ${(j: :)${(s.::.)0#_}} [options] Available commands: @@ -212,12 +212,12 @@ EOF local command="$1" shift - _omz::plugin::$command "$@" + $0::$command "$@" } function _omz::plugin::disable { if [[ -z "$1" ]]; then - echo >&2 "Usage: omz plugin disable [...]" + echo >&2 "Usage: ${(j: :)${(s.::.)0#_}} [...]" return 1 fi @@ -307,7 +307,7 @@ multi == 1 && length(\$0) > 0 { function _omz::plugin::enable { if [[ -z "$1" ]]; then - echo >&2 "Usage: omz plugin enable [...]" + echo >&2 "Usage: ${(j: :)${(s.::.)0#_}} [...]" return 1 fi @@ -383,7 +383,7 @@ multi == 1 && /^[^#]*\)/ { function _omz::plugin::info { if [[ -z "$1" ]]; then - echo >&2 "Usage: omz plugin info " + echo >&2 "Usage: ${(j: :)${(s.::.)0#_}} " return 1 fi @@ -430,7 +430,7 @@ function _omz::plugin::list { function _omz::plugin::load { if [[ -z "$1" ]]; then - echo >&2 "Usage: omz plugin load [...]" + echo >&2 "Usage: ${(j: :)${(s.::.)0#_}} [...]" return 1 fi @@ -477,9 +477,9 @@ function _omz::plugin::load { } function _omz::pr { - (( $# > 0 && $+functions[_omz::pr::$1] )) || { + (( $# > 0 && $+functions[$0::$1] )) || { cat >&2 < [options] +Usage: ${(j: :)${(s.::.)0#_}} [options] Available commands: @@ -493,7 +493,7 @@ EOF local command="$1" shift - _omz::pr::$command "$@" + $0::$command "$@" } function _omz::pr::clean { @@ -534,7 +534,7 @@ function _omz::pr::test { # Check the input if ! [[ -n "$1" && "$1" =~ ^[[:digit:]]+$ ]]; then - echo >&2 "Usage: omz pr test " + echo >&2 "Usage: ${(j: :)${(s.::.)0#_}} " return 1 fi @@ -619,9 +619,9 @@ function _omz::reload { } function _omz::theme { - (( $# > 0 && $+functions[_omz::theme::$1] )) || { + (( $# > 0 && $+functions[$0::$1] )) || { cat >&2 < [options] +Usage: ${(j: :)${(s.::.)0#_}} [options] Available commands: @@ -636,7 +636,7 @@ EOF local command="$1" shift - _omz::theme::$command "$@" + $0::$command "$@" } function _omz::theme::list { @@ -671,7 +671,7 @@ function _omz::theme::list { function _omz::theme::set { if [[ -z "$1" ]]; then - echo >&2 "Usage: omz theme set " + echo >&2 "Usage: ${(j: :)${(s.::.)0#_}} " return 1 fi @@ -739,7 +739,7 @@ EOF function _omz::theme::use { if [[ -z "$1" ]]; then - echo >&2 "Usage: omz theme use " + echo >&2 "Usage: ${(j: :)${(s.::.)0#_}} " return 1 fi -- cgit v1.2.3-70-g09d2 From 84931adcd465e9a3b5e38f3b416a1df2acc33801 Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Fri, 21 Jan 2022 19:03:35 +0100 Subject: fix: do not call chpwd hooks in subshells --- lib/cli.zsh | 10 +++++----- tools/check_for_upgrade.sh | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/cli.zsh b/lib/cli.zsh index 70076bcfb..2f3f293da 100644 --- a/lib/cli.zsh +++ b/lib/cli.zsh @@ -37,7 +37,7 @@ function _omz { elif (( CURRENT == 3 )); then case "$words[2]" in changelog) local -a refs - refs=("${(@f)$(cd "$ZSH"; command git for-each-ref --format="%(refname:short):%(subject)" refs/heads refs/tags)}") + refs=("${(@f)$(builtin cd -q "$ZSH"; command git for-each-ref --format="%(refname:short):%(subject)" refs/heads refs/tags)}") _describe 'command' refs ;; plugin) subcmds=( 'disable:Disable plugin(s)' @@ -176,7 +176,7 @@ function _omz::changelog { local version=${1:-HEAD} format=${3:-"--text"} if ( - cd "$ZSH" + builtin cd -q "$ZSH" ! command git show-ref --verify refs/heads/$version && \ ! command git show-ref --verify refs/tags/$version && \ ! command git rev-parse --verify "${version}^{commit}" @@ -761,7 +761,7 @@ function _omz::theme::use { } function _omz::update { - local last_commit=$(cd "$ZSH"; git rev-parse HEAD) + local last_commit=$(builtin cd -q "$ZSH"; git rev-parse HEAD) # Run update script if [[ "$1" != --unattended ]]; then @@ -777,7 +777,7 @@ function _omz::update { command rm -rf "$ZSH/log/update.lock" # Restart the zsh session if there were changes - if [[ "$1" != --unattended && "$(cd "$ZSH"; git rev-parse HEAD)" != "$last_commit" ]]; then + if [[ "$1" != --unattended && "$(builtin cd -q "$ZSH"; git rev-parse HEAD)" != "$last_commit" ]]; then # Old zsh versions don't have ZSH_ARGZERO local zsh="${ZSH_ARGZERO:-${functrace[-1]%:*}}" # Check whether to run a login shell @@ -787,7 +787,7 @@ function _omz::update { function _omz::version { ( - cd "$ZSH" + builtin cd -q "$ZSH" # Get the version name: # 1) try tag-like version diff --git a/tools/check_for_upgrade.sh b/tools/check_for_upgrade.sh index 729d8ecb5..3f6d35c3e 100644 --- a/tools/check_for_upgrade.sh +++ b/tools/check_for_upgrade.sh @@ -36,11 +36,11 @@ function current_epoch() { function is_update_available() { local branch - branch=${"$(cd "$ZSH"; git config --local oh-my-zsh.branch)":-master} + branch=${"$(cd -q "$ZSH"; git config --local oh-my-zsh.branch)":-master} local remote remote_url remote_repo - remote=${"$(cd "$ZSH"; git config --local oh-my-zsh.remote)":-origin} - remote_url=$(cd "$ZSH"; git config remote.$remote.url) + remote=${"$(cd -q "$ZSH"; git config --local oh-my-zsh.remote)":-origin} + remote_url=$(cd -q "$ZSH"; git config remote.$remote.url) local repo case "$remote_url" in @@ -58,7 +58,7 @@ function is_update_available() { # Get local HEAD. If this fails assume there are updates local local_head - local_head=$(cd "$ZSH"; git rev-parse $branch 2>/dev/null) || return 0 + local_head=$(cd -q "$ZSH"; git rev-parse $branch 2>/dev/null) || return 0 # Get remote HEAD. If no suitable command is found assume there are updates # On any other error, skip the update (connection may be down) @@ -136,7 +136,7 @@ function update_ohmyzsh() { fi # Test if Oh My Zsh directory is a git repository - if ! (cd "$ZSH" && LANG= git rev-parse &>/dev/null); then + if ! (cd -q "$ZSH" && LANG= git rev-parse &>/dev/null); then echo >&2 "[oh-my-zsh] Can't update: not a git repository." return fi -- cgit v1.2.3-70-g09d2 From f64cabc780496636b3e4f5283ef8d77c23f18e92 Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Mon, 24 Jan 2022 17:38:32 +0100 Subject: fix(cli): make sure to run `zsh` command if an alias exists (#9737) Fixes #9737 --- lib/cli.zsh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/cli.zsh b/lib/cli.zsh index 2f3f293da..edc10e722 100644 --- a/lib/cli.zsh +++ b/lib/cli.zsh @@ -289,7 +289,7 @@ multi == 1 && length(\$0) > 0 { } # Exit if the new .zshrc file has syntax errors - if ! zsh -n "$zdot/.zshrc"; then + if ! command zsh -n "$zdot/.zshrc"; then _omz::log error "broken syntax in '"${zdot/#$HOME/\~}/.zshrc"'. Rolling back changes..." command mv -f "$zdot/.zshrc" "$zdot/.zshrc.new" command mv -f "$zdot/.zshrc.bck" "$zdot/.zshrc" @@ -365,7 +365,7 @@ multi == 1 && /^[^#]*\)/ { } # Exit if the new .zshrc file has syntax errors - if ! zsh -n "$zdot/.zshrc"; then + if ! command zsh -n "$zdot/.zshrc"; then _omz::log error "broken syntax in '"${zdot/#$HOME/\~}/.zshrc"'. Rolling back changes..." command mv -f "$zdot/.zshrc" "$zdot/.zshrc.new" command mv -f "$zdot/.zshrc.bck" "$zdot/.zshrc" @@ -721,7 +721,7 @@ EOF } # Exit if the new .zshrc file has syntax errors - if ! zsh -n "$zdot/.zshrc"; then + if ! command zsh -n "$zdot/.zshrc"; then _omz::log error "broken syntax in '"${zdot/#$HOME/\~}/.zshrc"'. Rolling back changes..." command mv -f "$zdot/.zshrc" "$zdot/.zshrc.new" command mv -f "$zdot/.zshrc.bck" "$zdot/.zshrc" @@ -765,9 +765,9 @@ function _omz::update { # Run update script if [[ "$1" != --unattended ]]; then - ZSH="$ZSH" zsh -f "$ZSH/tools/upgrade.sh" --interactive || return $? + ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" --interactive || return $? else - ZSH="$ZSH" zsh -f "$ZSH/tools/upgrade.sh" || return $? + ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" || return $? fi # Update last updated file -- cgit v1.2.3-70-g09d2 From e1a9d0ce3e142003bf137e8ca3e204474b8c148f Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Wed, 2 Feb 2022 23:02:23 +0100 Subject: fix(cli): allow `omz` commands to be used in a script (#10645) The commands `omz plugin {enable,disable}` and `omz theme set` automatically reload the zsh session on success. With this change, the CLI checks whether the commands are run in an interactive session before reloading the zsh session. This change also conditionally sets the completion function for `omz` so that it's not done in a non-interactive session. --- lib/cli.zsh | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'lib') diff --git a/lib/cli.zsh b/lib/cli.zsh index edc10e722..e7f997013 100644 --- a/lib/cli.zsh +++ b/lib/cli.zsh @@ -105,7 +105,10 @@ function _omz { return 0 } -compdef _omz omz +# If run from a script, do not set the completion function +if (( ${+functions[compdef]} )); then + compdef _omz omz +fi ## Utility functions @@ -299,10 +302,8 @@ multi == 1 && length(\$0) > 0 { # Restart the zsh session if there were no errors _omz::log info "plugins disabled: ${(j:, :)dis_plugins}." - # Old zsh versions don't have ZSH_ARGZERO - local zsh="${ZSH_ARGZERO:-${functrace[-1]%:*}}" - # Check whether to run a login shell - [[ "$zsh" = -* || -o login ]] && exec -l "${zsh#-}" || exec "$zsh" + # Only reload zsh if run in an interactive session + [[ ! -o interactive ]] || _omz::reload } function _omz::plugin::enable { @@ -375,10 +376,8 @@ multi == 1 && /^[^#]*\)/ { # Restart the zsh session if there were no errors _omz::log info "plugins enabled: ${(j:, :)add_plugins}." - # Old zsh versions don't have ZSH_ARGZERO - local zsh="${ZSH_ARGZERO:-${functrace[-1]%:*}}" - # Check whether to run a login shell - [[ "$zsh" = -* || -o login ]] && exec -l "${zsh#-}" || exec "$zsh" + # Only reload zsh if run in an interactive session + [[ ! -o interactive ]] || _omz::reload } function _omz::plugin::info { @@ -731,10 +730,8 @@ EOF # Restart the zsh session if there were no errors _omz::log info "'$1' theme set correctly." - # Old zsh versions don't have ZSH_ARGZERO - local zsh="${ZSH_ARGZERO:-${functrace[-1]%:*}}" - # Check whether to run a login shell - [[ "$zsh" = -* || -o login ]] && exec -l "${zsh#-}" || exec "$zsh" + # Only reload zsh if run in an interactive session + [[ ! -o interactive ]] || _omz::reload } function _omz::theme::use { -- cgit v1.2.3-70-g09d2 From 0da33ca22be19452e26ed44aef8e99972d0bf866 Mon Sep 17 00:00:00 2001 From: Carlo Sala Date: Thu, 10 Feb 2022 11:50:04 +0100 Subject: fix(cli): disable GPG signing in `omz pr test` to avoid key prompt (#10677) --- lib/cli.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/cli.zsh b/lib/cli.zsh index e7f997013..c2fba8556 100644 --- a/lib/cli.zsh +++ b/lib/cli.zsh @@ -573,7 +573,7 @@ function _omz::pr::test { # Rebase pull request branch against the current master _omz::log info "rebasing PR #$1..." - command git rebase master ohmyzsh/pull-$1 || { + command git rebase --no-gpg-sign master ohmyzsh/pull-$1 || { command git rebase --abort &>/dev/null _omz::log warn "could not rebase PR #$1 on top of master." _omz::log warn "you might not see the latest stable changes." -- cgit v1.2.3-70-g09d2 From ef3f7c43a91eb2c90098843b0ee9193bb52cdc96 Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Sun, 13 Feb 2022 18:59:27 +0100 Subject: fix: apply workaround patch for vcs_info (CVE-2021-45444) This lib function applies a patch to the VCS_INFO_formats function in zsh versions from v5.0.3 until v5.8, which don't quote % chars in some arguments received. Normally that just means that some % characters in these strings (branch names, directories, etc.) will be incorrectly parsed as formatting sequences. With CVE-2021-45444, however, this means that one of these strings from a malicious source (e.g. a malicious git repository) can trigger command injection and run arbitrary code in the user's machine when visiting such git repository. Zsh 5.8.1 fixes this vulnerability [1], but older vcs_info setups still need a workaround such as this one to patch the vulnerability. [1] https://github.com/zsh-users/zsh/commit/c3ea1e5d52eff8b7b172fa8c1ccc3462b43b2790 --- lib/vcs_info.zsh | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 lib/vcs_info.zsh (limited to 'lib') diff --git a/lib/vcs_info.zsh b/lib/vcs_info.zsh new file mode 100644 index 000000000..01dcd90b6 --- /dev/null +++ b/lib/vcs_info.zsh @@ -0,0 +1,50 @@ +# Impacted versions go from v5.0.3 to v5.8 (v5.8.1 is the first patched version) +autoload -Uz is-at-least +if is-at-least 5.8.1 || ! is-at-least 5.0.3; then + return +fi + +# Quote necessary $hook_com[] items just before they are used +# in the line "VCS_INFO_hook 'post-backend'" of the VCS_INFO_formats +# function, where is: +# +# base: the full path of the repository's root directory. +# base-name: the name of the repository's root directory. +# branch: the name of the currently checked out branch. +# misc: a string that may contain anything the vcs_info backend wants. +# revision: an identifier of the currently checked out revision. +# subdir: the path of the current directory relative to the +# repository's root directory. +# +# This patch %-quotes these fields previous to their use in vcs_info hooks and +# the zformat call and, eventually, when they get expanded in the prompt. +# It's important to quote these here, and not later after hooks have modified the +# fields, because then we could be quoting % characters from valid prompt sequences, +# like %F{color}, %B, etc. +# +# 32 │ hook_com[subdir]="$(VCS_INFO_reposub ${hook_com[base]})" +# 33 │ hook_com[subdir_orig]="${hook_com[subdir]}" +# 34 │ +# 35 + │ for tmp in base base-name branch misc revision subdir; do +# 36 + │ hook_com[$tmp]="${hook_com[$tmp]//\%/%%}" +# 37 + │ done +# 38 + │ +# 39 │ VCS_INFO_hook 'post-backend' +# +# This is especially important so that no command substitution is performed +# due to malicious input as a consequence of CVE-2021-45444, which affects +# zsh versions from 5.0.3 to 5.8. +# +autoload -Uz +X regexp-replace VCS_INFO_formats + +# We use $tmp here because it's already a local variable in VCS_INFO_formats +typeset PATCH='for tmp (base base-name branch misc revision subdir) hook_com[$tmp]="${hook_com[$tmp]//\%/%%}"' +# Unique string to avoid reapplying the patch if this code gets called twice +typeset PATCH_ID=vcs_info-patch-9b9840f2-91e5-4471-af84-9e9a0dc68c1b +# Only patch the VCS_INFO_formats function if not already patched +if [[ "$functions[VCS_INFO_formats]" != *$PATCH_ID* ]]; then + regexp-replace 'functions[VCS_INFO_formats]' \ + "VCS_INFO_hook 'post-backend'" \ + ': ${PATCH_ID}; ${PATCH}; ${MATCH}' +fi +unset PATCH PATCH_ID -- cgit v1.2.3-70-g09d2