Compare commits

2 Commits
Author SHA1 Message Date
Robby RussellandClaude Opus 5 97dfe1ae54 fix(init): only accept an object ID as the resolved revision
A malformed HEAD or loose ref was copied into the zcompdump metadata as
though it had resolved, so a corrupt file could make #omz revision:
differ from git rev-parse HEAD instead of taking the fallback.

Fold the three resolution paths into one exit and check the result is a
40 or 64 character hex object ID, so symbolic refs, malformed files and
missed packed entries all fall through to git.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 08:25:57 -07:00
Robby RussellandClaude Opus 5 c6d78edc8f fix(init): keep the revision helper's REPLY out of the global scope
_omz_git_head reports through $REPLY, which stayed set for the rest of
startup and could overwrite caller state or be mistaken for the result
of an unrelated read. Call it inside an anonymous function that declares
REPLY local.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 07:56:48 -07:00
+24 -15
View File
@@ -136,25 +136,34 @@ _omz_git_head() {
[[ -r "$gitdir/HEAD" ]] || return 1
read -r head 2>/dev/null < "$gitdir/HEAD" || return 1
# detached HEAD: the file holds the commit itself
[[ "$head" = ref:\ * ]] || { REPLY="$head"; return 0 }
ref="${head#ref: }"
if [[ -r "$common/$ref" ]]; then
read -r REPLY 2>/dev/null < "$common/$ref" || return 1
[[ "$REPLY" != ref:\ * ]] || return 1
return 0
if [[ "$head" = ref:\ * ]]; then
ref="${head#ref: }"
if [[ -r "$common/$ref" ]]; then
read -r REPLY 2>/dev/null < "$common/$ref" || return 1
elif [[ -r "$common/packed-refs" ]]; then
lines=("${(@f)$(<"$common/packed-refs")}")
REPLY="${lines[(r)* ${(b)ref}]%% *}"
else
return 1
fi
else
# detached HEAD: the file holds the commit itself
REPLY="$head"
fi
[[ -r "$common/packed-refs" ]] || return 1
lines=("${(@f)$(<"$common/packed-refs")}")
REPLY="${lines[(r)* ${(b)ref}]%% *}"
[[ -n "$REPLY" ]]
# only an object ID is a usable answer: a symbolic ref, a malformed file or
# a missed packed entry all fall through to the git fallback instead
[[ -n "$REPLY" && -z "${REPLY//[0-9a-f]/}" ]] \
&& (( ${#REPLY} == 40 || ${#REPLY} == 64 ))
}
# Construct zcompdump OMZ metadata
_omz_git_head || REPLY="$(builtin cd -q "$ZSH"; git rev-parse HEAD 2>/dev/null)"
zcompdump_revision="#omz revision: $REPLY"
# Construct zcompdump OMZ metadata. The helper reports through $REPLY, so
# call it in a scope that keeps that out of the global namespace.
() {
local REPLY
_omz_git_head || REPLY="$(builtin cd -q "$ZSH"; git rev-parse HEAD 2>/dev/null)"
typeset -g zcompdump_revision="#omz revision: $REPLY"
}
zcompdump_fpath="#omz fpath: $fpath"
unset -f _omz_git_head