mirror of
https://github.com/robbyrussell/oh-my-zsh.git
synced 2026-09-25 04:26:08 +02:00
perf(vcs_info): apply the %-quoting patch on first use
lib/vcs_info.zsh loaded VCS_INFO_formats and regexp-replace and patched the function body on every startup, although only themes that call vcs_info ever need it. Define a VCS_INFO_formats wrapper that loads and patches the real function the first time it's called, then replaces itself with it. `autoload` doesn't override an existing function, so the wrapper survives a theme's `autoload -Uz vcs_info` and vcs_info's own autoload of VCS_INFO_*. Verified that a branch named `evil%n%m` still renders literally after prompt expansion, as with the eager patch (CVE-2021-45444 mitigation). Measured on macOS arm64, zsh 5.9: 1.6 ms -> 0.1 ms per interactive start. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
426650fbe8
commit
a0fa610df3
+21
-12
@@ -38,16 +38,25 @@
|
||||
# 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 2>/dev/null || return 0
|
||||
# The patch is applied when VCS_INFO_formats is first called, since loading
|
||||
# and patching it on every startup costs time in shells that never use
|
||||
# vcs_info. `autoload` doesn't replace an already defined function, so this
|
||||
# wrapper survives a later `autoload -Uz vcs_info` in a theme or .zshrc, and
|
||||
# vcs_info's own `autoload -Uz VCS_INFO_formats`.
|
||||
function VCS_INFO_formats {
|
||||
unfunction VCS_INFO_formats
|
||||
autoload -Uz +X regexp-replace VCS_INFO_formats 2>/dev/null || return 1
|
||||
|
||||
# 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
|
||||
# We use $tmp here because it's already a local variable in VCS_INFO_formats
|
||||
local 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
|
||||
local 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
|
||||
|
||||
VCS_INFO_formats "$@"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user