Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit 12188a8

Browse files
committed
Merge branch 'rh/prompt-pcmode-avoid-eval-on-refname' into maint
* rh/prompt-pcmode-avoid-eval-on-refname: git-prompt.sh: don't assume the shell expands the value of PS1
2 parents 64d8c31 + 1e4119c commit 12188a8

File tree

2 files changed

+42
-20
lines changed

2 files changed

+42
-20
lines changed

contrib/completion/git-prompt.sh

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,7 @@ __git_ps1_show_upstream ()
209209
if [[ -n "$count" && -n "$name" ]]; then
210210
__git_ps1_upstream_name=$(git rev-parse \
211211
--abbrev-ref "$upstream" 2>/dev/null)
212-
if [ $pcmode = yes ]; then
213-
# see the comments around the
214-
# __git_ps1_branch_name variable below
212+
if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
215213
p="$p \${__git_ps1_upstream_name}"
216214
else
217215
p="$p ${__git_ps1_upstream_name}"
@@ -301,6 +299,43 @@ __git_ps1 ()
301299
;;
302300
esac
303301

302+
# ps1_expanded: This variable is set to 'yes' if the shell
303+
# subjects the value of PS1 to parameter expansion:
304+
#
305+
# * bash does unless the promptvars option is disabled
306+
# * zsh does not unless the PROMPT_SUBST option is set
307+
# * POSIX shells always do
308+
#
309+
# If the shell would expand the contents of PS1 when drawing
310+
# the prompt, a raw ref name must not be included in PS1.
311+
# This protects the user from arbitrary code execution via
312+
# specially crafted ref names. For example, a ref named
313+
# 'refs/heads/$(IFS=_;cmd=sudo_rm_-rf_/;$cmd)' might cause the
314+
# shell to execute 'sudo rm -rf /' when the prompt is drawn.
315+
#
316+
# Instead, the ref name should be placed in a separate global
317+
# variable (in the __git_ps1_* namespace to avoid colliding
318+
# with the user's environment) and that variable should be
319+
# referenced from PS1. For example:
320+
#
321+
# __git_ps1_foo=$(do_something_to_get_ref_name)
322+
# PS1="...stuff...\${__git_ps1_foo}...stuff..."
323+
#
324+
# If the shell does not expand the contents of PS1, the raw
325+
# ref name must be included in PS1.
326+
#
327+
# The value of this variable is only relevant when in pcmode.
328+
#
329+
# Assume that the shell follows the POSIX specification and
330+
# expands PS1 unless determined otherwise. (This is more
331+
# likely to be correct if the user has a non-bash, non-zsh
332+
# shell and safer than the alternative if the assumption is
333+
# incorrect.)
334+
#
335+
local ps1_expanded=yes
336+
[ -z "$ZSH_VERSION" ] || [[ -o PROMPT_SUBST ]] || ps1_expanded=no
337+
[ -z "$BASH_VERSION" ] || shopt -q promptvars || ps1_expanded=no
338+
304339
local repo_info rev_parse_exit_code
305340
repo_info="$(git rev-parse --git-dir --is-inside-git-dir \
306341
--is-bare-repository --is-inside-work-tree \
@@ -450,21 +485,8 @@ __git_ps1 ()
450485
fi
451486

452487
b=${b##refs/heads/}
453-
if [ $pcmode = yes ]; then
454-
# In pcmode (and only pcmode) the contents of
455-
# $gitstring are subject to expansion by the shell.
456-
# Avoid putting the raw ref name in the prompt to
457-
# protect the user from arbitrary code execution via
458-
# specially crafted ref names (e.g., a ref named
459-
# '$(IFS=_;cmd=sudo_rm_-rf_/;$cmd)' would execute
460-
# 'sudo rm -rf /' when the prompt is drawn). Instead,
461-
# put the ref name in a new global variable (in the
462-
# __git_ps1_* namespace to avoid colliding with the
463-
# user's environment) and reference that variable from
464-
# PS1.
488+
if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
465489
__git_ps1_branch_name=$b
466-
# note that the $ is escaped -- the variable will be
467-
# expanded later (when it's time to draw the prompt)
468490
b="\${__git_ps1_branch_name}"
469491
fi
470492

t/t9903-bash-prompt.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -578,12 +578,12 @@ test_expect_success 'prompt - bash color pc mode - untracked files status indica
578578
'
579579

580580
test_expect_success 'prompt - zsh color pc mode' '
581-
printf "BEFORE: (%%F{green}\${__git_ps1_branch_name}%%f):AFTER\\nmaster" >expected &&
581+
printf "BEFORE: (%%F{green}master%%f):AFTER" >expected &&
582582
(
583583
ZSH_VERSION=5.0.0 &&
584584
GIT_PS1_SHOWCOLORHINTS=y &&
585-
__git_ps1 "BEFORE:" ":AFTER" >"$actual"
586-
printf "%s\\n%s" "$PS1" "${__git_ps1_branch_name}" >"$actual"
585+
__git_ps1 "BEFORE:" ":AFTER" &&
586+
printf "%s" "$PS1" >"$actual"
587587
) &&
588588
test_cmp expected "$actual"
589589
'

0 commit comments

Comments
 (0)