@@ -14,14 +14,15 @@ set -euo pipefail
1414# ---------------------------------------------------------------------------
1515INPUT=" $( cat) "
1616
17- TOOL_NAME=" $( printf ' %s' " $INPUT " | python3 -c " import sys,json; print(json.load(sys.stdin).get(' tool_name','')) " 2> /dev/null || true) "
17+ TOOL_NAME=" $( printf ' %s' " $INPUT " | jq -r ' . tool_name // "" ' 2> /dev/null || true) "
1818
19- # Only validate Bash commands — allow everything else through
20- if [[ " $TOOL_NAME " != " Bash" ]]; then
19+ # Only validate Bash commands — allow everything else through.
20+ # If TOOL_NAME is empty (parse failure), fall through to check the command anyway (fail closed).
21+ if [[ -n " $TOOL_NAME " && " $TOOL_NAME " != " Bash" ]]; then
2122 exit 0
2223fi
2324
24- COMMAND=" $( printf ' %s' " $INPUT " | python3 -c " import sys,json; print(json.load(sys.stdin).get(' tool_input',{}).get(' command','')) " 2> /dev/null || true) "
25+ COMMAND=" $( printf ' %s' " $INPUT " | jq -r ' . tool_input. command // "" ' 2> /dev/null || true) "
2526
2627if [[ -z " $COMMAND " ]]; then
2728 exit 0
@@ -136,20 +137,19 @@ BLOCKED_PATTERNS=(
136137# ---------------------------------------------------------------------------
137138check_command () {
138139 local cmd=" $1 "
139- # Trim leading/trailing whitespace
140- cmd=" $( echo " $cmd " | sed ' s/^[[:space:]]*//;s/[[:space:]]*$//' ) "
140+ # Trim leading/trailing whitespace using parameter expansion
141+ cmd=" ${cmd# " ${cmd%% [![:space:]]* } " } "
142+ cmd=" ${cmd% " ${cmd##* [![:space:]]} " } "
141143
142144 if [[ -z " $cmd " ]]; then
143145 return 0
144146 fi
145147
146- # Convert to lowercase for case-insensitive matching
147- local cmd_lower
148- cmd_lower=" $( echo " $cmd " | tr ' [:upper:]' ' [:lower:]' ) "
148+ # Convert to lowercase using parameter expansion
149+ local cmd_lower=" ${cmd,,} "
149150
150151 for pattern in " ${BLOCKED_PATTERNS[@]} " ; do
151- local pattern_lower
152- pattern_lower=" $( echo " $pattern " | tr ' [:upper:]' ' [:lower:]' ) "
152+ local pattern_lower=" ${pattern,,} "
153153
154154 # shellcheck disable=SC2254
155155 if [[ " $cmd_lower " == $pattern_lower ]]; then
@@ -164,8 +164,12 @@ check_command() {
164164# ---------------------------------------------------------------------------
165165# 4. Split on pipes and command chains, then check each sub-command
166166# ---------------------------------------------------------------------------
167- # Replace common chain operators with a delimiter
168- NORMALIZED=" $( echo " $COMMAND " | sed ' s/&&/\n/g; s/||/\n/g; s/;/\n/g; s/|/\n/g' ) "
167+ # Replace common chain operators with newlines using parameter expansion
168+ # Order matters: replace && and || before | to avoid double-splitting ||
169+ NORMALIZED=" ${COMMAND// &&/ $' \n ' } "
170+ NORMALIZED=" ${NORMALIZED// ||/ $' \n ' } "
171+ NORMALIZED=" ${NORMALIZED// ;/ $' \n ' } "
172+ NORMALIZED=" ${NORMALIZED// |/ $' \n ' } "
169173
170174while IFS= read -r subcmd; do
171175 check_command " $subcmd "
0 commit comments