Skip to content

Commit fe5aedb

Browse files
committed
Include the no-op colon reduction in __bp_sanitize_string
1 parent 299080e commit fe5aedb

File tree

2 files changed

+69
-13
lines changed

2 files changed

+69
-13
lines changed

bash-preexec.sh

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,46 @@ __bp_trim_whitespace() {
121121

122122

123123
# Trims whitespace and removes any leading or trailing semicolons from $2 and
124-
# writes the resulting string to the variable name passed as $1. Used for
125-
# manipulating substrings in PROMPT_COMMAND
124+
# writes the resulting string to the variable name passed as $1. This also
125+
# removes the no-op colons, which are converted from the hooks to remove. Used
126+
# for manipulating substrings in PROMPT_COMMAND
126127
__bp_sanitize_string() {
127-
local var=${1:?} text=${2:-} sanitized
128-
__bp_trim_whitespace sanitized "$text"
128+
local var=${1:?} sanitized=${2:-}
129+
130+
local unset_extglob=
131+
if ! shopt -q extglob; then
132+
unset_extglob=yes
133+
shopt -s extglob
134+
fi
135+
136+
# We specify newline character through the variable `nl' because $'\n'
137+
# inside "${var//...}" is treated literally as "\$'\\n'" when `extquote' is
138+
# unset (shopt -u extquote). (Note: Bash 5.2's extquote seems to be buggy.)
139+
local tmp sp=$' \t' nl=$'\n'
140+
while
141+
# Quoting parameter expansions $nl in PAT of ${var//PAT/REP} is
142+
# required by shellcheck. On the other hand, we should not quote the
143+
# parameter expansions $nl in REP because the quotes will remain in the
144+
# replaced result with `shopt -s compat42'.
145+
tmp="${sanitized//[";$nl"]*(["$sp"]):*(["$sp"])[";$nl"]/$nl}"
146+
[[ "$tmp" != "$sanitized" ]]
147+
do
148+
sanitized="$tmp"
149+
done
150+
sanitized="${sanitized#:*(["$sp"])[";$nl"]}"
151+
sanitized="${sanitized%[";$nl"]*(["$sp"]):}"
152+
__bp_trim_whitespace sanitized "$sanitized"
129153
sanitized=${sanitized%;}
130154
sanitized=${sanitized#;}
131155
__bp_trim_whitespace sanitized "$sanitized"
156+
if [[ "$sanitized" == ":" ]]; then
157+
sanitized=
158+
fi
132159
printf -v "$var" '%s' "$sanitized"
160+
161+
if [[ -n "$unset_extglob" ]]; then
162+
shopt -u extglob
163+
fi
133164
}
134165

135166
# This function is installed as part of the PROMPT_COMMAND;
@@ -323,20 +354,12 @@ __bp_install() {
323354
shopt -s extdebug > /dev/null 2>&1
324355
fi;
325356

326-
# We specify newline character through the variable `nl' because $'\n'
327-
# inside "${var//...}" is treated literally as "\$'\\n'" when `extquote' is
328-
# unset (shopt -u extquote). (Note: Bash 5.2's extquote seems to be buggy.)
329-
local existing_prompt_command nl=$'\n'
357+
local existing_prompt_command
330358
# Remove setting our trap install string and sanitize the existing prompt command string
331359
existing_prompt_command="${PROMPT_COMMAND:-}"
332360
# Edge case of appending to PROMPT_COMMAND
333361
existing_prompt_command="${existing_prompt_command//$__bp_install_string/:}" # no-op
334-
existing_prompt_command="${existing_prompt_command//$nl:$nl/$nl}" # remove known-token only
335-
existing_prompt_command="${existing_prompt_command//$nl:;/$nl}" # remove known-token only
336362
__bp_sanitize_string existing_prompt_command "$existing_prompt_command"
337-
if [[ "${existing_prompt_command:-:}" == ":" ]]; then
338-
existing_prompt_command=
339-
fi
340363

341364
# Install our hooks in PROMPT_COMMAND to allow our trap to know when we've
342365
# actually entered something.

test/bash-preexec.bats

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,39 @@ set_exit_code_and_run_precmd() {
116116

117117
}
118118

119+
@test "__bp_sanitize_string should remove no-op colons" {
120+
__bp_sanitize_string output ':'
121+
[ "$output" == "" ]
122+
123+
__bp_sanitize_string output $':\n:'
124+
[ "$output" == "" ]
125+
126+
__bp_sanitize_string output $':\n:;echo USER1'
127+
[ "$output" == "echo USER1" ]
128+
129+
__bp_sanitize_string output $'echo USER2\n:\necho USER3'
130+
expected_result=$'echo USER2\necho USER3'
131+
[ "$output" == "$expected_result" ]
132+
133+
__bp_sanitize_string output $'echo USER4;:;echo USER5'
134+
expected_result=$'echo USER4\necho USER5'
135+
[ "$output" == "$expected_result" ]
136+
137+
__bp_sanitize_string output $'echo USER6;:\necho USER7'
138+
expected_result=$'echo USER6\necho USER7'
139+
[ "$output" == "$expected_result" ]
140+
141+
__bp_sanitize_string output $':\n: ; echo USER8'
142+
[ "$output" == "echo USER8" ]
143+
144+
__bp_sanitize_string output $':\n: ; echo USER9'
145+
[ "$output" == "echo USER9" ]
146+
147+
__bp_sanitize_string output $'echo USER10 ; :\n: ; echo USER11'
148+
expected_result=$'echo USER10 \n echo USER11'
149+
[ "$output" == "$expected_result" ]
150+
}
151+
119152
@test "Appending to PROMPT_COMMAND should work after bp_install" {
120153
bp_install
121154

0 commit comments

Comments
 (0)