Skip to content

Commit

Permalink
Include the no-op colon reduction in __bp_sanitize_string
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Feb 3, 2024
1 parent 299080e commit fe5aedb
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 13 deletions.
49 changes: 36 additions & 13 deletions bash-preexec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,46 @@ __bp_trim_whitespace() {


# Trims whitespace and removes any leading or trailing semicolons from $2 and
# writes the resulting string to the variable name passed as $1. Used for
# manipulating substrings in PROMPT_COMMAND
# writes the resulting string to the variable name passed as $1. This also
# removes the no-op colons, which are converted from the hooks to remove. Used
# for manipulating substrings in PROMPT_COMMAND
__bp_sanitize_string() {
local var=${1:?} text=${2:-} sanitized
__bp_trim_whitespace sanitized "$text"
local var=${1:?} sanitized=${2:-}

local unset_extglob=
if ! shopt -q extglob; then
unset_extglob=yes
shopt -s extglob
fi

# We specify newline character through the variable `nl' because $'\n'
# inside "${var//...}" is treated literally as "\$'\\n'" when `extquote' is
# unset (shopt -u extquote). (Note: Bash 5.2's extquote seems to be buggy.)
local tmp sp=$' \t' nl=$'\n'
while
# Quoting parameter expansions $nl in PAT of ${var//PAT/REP} is
# required by shellcheck. On the other hand, we should not quote the
# parameter expansions $nl in REP because the quotes will remain in the
# replaced result with `shopt -s compat42'.
tmp="${sanitized//[";$nl"]*(["$sp"]):*(["$sp"])[";$nl"]/$nl}"
[[ "$tmp" != "$sanitized" ]]
do
sanitized="$tmp"
done
sanitized="${sanitized#:*(["$sp"])[";$nl"]}"
sanitized="${sanitized%[";$nl"]*(["$sp"]):}"
__bp_trim_whitespace sanitized "$sanitized"
sanitized=${sanitized%;}
sanitized=${sanitized#;}
__bp_trim_whitespace sanitized "$sanitized"
if [[ "$sanitized" == ":" ]]; then
sanitized=
fi
printf -v "$var" '%s' "$sanitized"

if [[ -n "$unset_extglob" ]]; then
shopt -u extglob
fi
}

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

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

# Install our hooks in PROMPT_COMMAND to allow our trap to know when we've
# actually entered something.
Expand Down
33 changes: 33 additions & 0 deletions test/bash-preexec.bats
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,39 @@ set_exit_code_and_run_precmd() {

}

@test "__bp_sanitize_string should remove no-op colons" {
__bp_sanitize_string output ':'
[ "$output" == "" ]

__bp_sanitize_string output $':\n:'
[ "$output" == "" ]

__bp_sanitize_string output $':\n:;echo USER1'
[ "$output" == "echo USER1" ]

__bp_sanitize_string output $'echo USER2\n:\necho USER3'
expected_result=$'echo USER2\necho USER3'
[ "$output" == "$expected_result" ]

__bp_sanitize_string output $'echo USER4;:;echo USER5'
expected_result=$'echo USER4\necho USER5'
[ "$output" == "$expected_result" ]

__bp_sanitize_string output $'echo USER6;:\necho USER7'
expected_result=$'echo USER6\necho USER7'
[ "$output" == "$expected_result" ]

__bp_sanitize_string output $':\n: ; echo USER8'
[ "$output" == "echo USER8" ]

__bp_sanitize_string output $':\n: ; echo USER9'
[ "$output" == "echo USER9" ]

__bp_sanitize_string output $'echo USER10 ; :\n: ; echo USER11'
expected_result=$'echo USER10 \n echo USER11'
[ "$output" == "$expected_result" ]
}

@test "Appending to PROMPT_COMMAND should work after bp_install" {
bp_install

Expand Down

0 comments on commit fe5aedb

Please sign in to comment.