From 67ec4ccd13bb3381d5c78d9f876fcb49fd9059c1 Mon Sep 17 00:00:00 2001 From: Dhruba Datta <74358627+dhruba-datta@users.noreply.github.com> Date: Sat, 16 May 2026 01:33:15 +0600 Subject: [PATCH] fix(examples/hooks): bash_command_validator regex false negatives MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes anthropics/claude-code#59441. Two regex bugs in _VALIDATION_RULES caused silent false negatives: 1. grep: ^grep\b(?!.*\|) exempted leading grep in pipelines (e.g. "grep foo | wc -l") because the (?!.*\|) lookahead fails on any pipe anywhere in the string. The ^grep anchor already excludes downstream uses like "cat foo | grep bar", so the lookahead was dead code creating false negatives. Dropped it. 2. find: ^find\s+\S+\s+-name\b only matched "find PATH -name" shape. The most common real form — "find PATH -type f -name '*.log'" — was missed because the regex required -name to be adjacent to the path token. Changed to ^find\s+\S+.*\s-name\b to allow arbitrary predicates between the path and -name. Verified against the full case matrix from the issue plus regression guards (downstream grep, xargs find, findstr, find without -name). --- examples/hooks/bash_command_validator_example.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/hooks/bash_command_validator_example.py b/examples/hooks/bash_command_validator_example.py index 53ab7a829e..518ec916fd 100644 --- a/examples/hooks/bash_command_validator_example.py +++ b/examples/hooks/bash_command_validator_example.py @@ -32,14 +32,18 @@ import re import sys -# Define validation rules as a list of (regex pattern, message) tuples +# Define validation rules as a list of (regex pattern, message) tuples. +# +# Each pattern is anchored to the start of the command (^) so it matches +# only when the listed command is the leading binary of the pipeline. +# Downstream uses (e.g. `cat foo | grep bar`) are intentionally not flagged. _VALIDATION_RULES = [ ( - r"^grep\b(?!.*\|)", + r"^grep\b", "Use 'rg' (ripgrep) instead of 'grep' for better performance and features", ), ( - r"^find\s+\S+\s+-name\b", + r"^find\s+\S+.*\s-name\b", "Use 'rg --files | rg pattern' or 'rg --files -g pattern' instead of 'find -name' for better performance", ), ]