Skip to content

Commit 7f5cc9d

Browse files
justin808claude
andcommitted
fix: handle filenames with spaces safely in hook scripts
Fixed critical shell scripting issues in all helper scripts: Security & Reliability Fixes: - Use proper quoted variable expansion ("$@" instead of $files) - Use bash arrays instead of string concatenation for file lists - Protect against command injection with special characters - Handle filenames with spaces, newlines, and special chars safely Specific Changes: - rubocop-lint: Use "$@" for file arguments, safer printf - rspec-affected: Use array for spec_files, proper quoting - check-trailing-newlines: Use array for failed_files Output Fixes: - Added missing spaces in error messages (lines 27-28) - Use array expansion with spaces: ${files[*]} All scripts now follow bash best practices for safe file handling. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 77ff7fc commit 7f5cc9d

File tree

3 files changed

+19
-25
lines changed

3 files changed

+19
-25
lines changed

bin/lefthook/check-trailing-newlines

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,28 @@
22
# Check for trailing newlines on staged files
33
set -euo pipefail
44

5-
files="$*"
6-
7-
if [ -z "$files" ]; then
5+
if [ $# -eq 0 ]; then
86
echo "✅ No files to check for trailing newlines"
97
exit 0
108
fi
119

1210
echo "🔍 Checking trailing newlines on staged files..."
1311

14-
failed_files=""
15-
for file in $files; do
12+
failed_files=()
13+
for file in "$@"; do
1614
if [ -f "$file" ] && [ -s "$file" ]; then
1715
if ! tail -c 1 "$file" | grep -q '^$'; then
1816
echo "❌ Missing trailing newline: $file"
19-
failed_files="$failed_files $file"
17+
failed_files+=("$file")
2018
fi
2119
fi
2220
done
2321

24-
if [ -n "$failed_files" ]; then
22+
if [ ${#failed_files[@]} -gt 0 ]; then
2523
echo ""
2624
echo "❌ Trailing newline check failed!"
27-
echo "💡 Add trailing newlines to:$failed_files"
28-
echo "🔧 Quick fix: for file in$failed_files; do echo >> \"\$file\"; done"
25+
echo "💡 Add trailing newlines to: ${failed_files[*]}"
26+
echo "🔧 Quick fix: for file in ${failed_files[*]}; do echo >> \"\$file\"; done"
2927
echo "🚫 Skip hook: git commit --no-verify"
3028
exit 1
3129
fi

bin/lefthook/rspec-affected

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,35 @@
22
# Run RSpec tests for affected files
33
set -euo pipefail
44

5-
files="$*"
6-
7-
if [ -z "$files" ]; then
5+
if [ $# -eq 0 ]; then
86
echo "✅ No Ruby files changed"
97
exit 0
108
fi
119

1210
# Find corresponding spec files for changed lib files
13-
spec_files=""
14-
for file in $files; do
11+
spec_files=()
12+
for file in "$@"; do
1513
if [[ $file == lib/* ]]; then
1614
# Convert lib/package_json/foo.rb to spec/package_json/foo_spec.rb
1715
spec_file=$(echo "$file" | sed 's|^lib/|spec/|' | sed 's|\.rb$|_spec.rb|')
1816
if [ -f "$spec_file" ]; then
19-
spec_files="$spec_files $spec_file"
17+
spec_files+=("$spec_file")
2018
fi
2119
elif [[ $file == spec/* ]]; then
2220
# If it's already a spec file, include it
23-
spec_files="$spec_files $file"
21+
spec_files+=("$file")
2422
fi
2523
done
2624

27-
if [ -z "$spec_files" ]; then
25+
if [ ${#spec_files[@]} -eq 0 ]; then
2826
echo "✅ No corresponding spec files found for changed files"
2927
exit 0
3028
fi
3129

3230
echo "🧪 Running affected RSpec tests:"
33-
printf " %s\n" $spec_files
31+
printf " %s\n" "${spec_files[@]}"
3432

35-
if ! bundle exec rspec $spec_files; then
33+
if ! bundle exec rspec "${spec_files[@]}"; then
3634
echo ""
3735
echo "❌ Tests failed!"
3836
echo "💡 Run full suite: bundle exec rspec"

bin/lefthook/rubocop-lint

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,18 @@
22
# Lint Ruby files with RuboCop
33
set -euo pipefail
44

5-
files="$*"
6-
7-
if [ -z "$files" ]; then
5+
if [ $# -eq 0 ]; then
86
echo "✅ No Ruby files to lint"
97
exit 0
108
fi
119

1210
echo "🔍 RuboCop on staged Ruby files:"
13-
printf " %s\n" $files
11+
printf " %s\n" "$@"
1412

15-
if ! bundle exec rubocop --force-exclusion --display-cop-names -- $files; then
13+
if ! bundle exec rubocop --force-exclusion --display-cop-names -- "$@"; then
1614
echo ""
1715
echo "❌ RuboCop check failed!"
18-
echo "💡 Auto-fix: bundle exec rubocop -a --force-exclusion -- $files"
16+
echo "💡 Auto-fix: bundle exec rubocop -a --force-exclusion -- <files>"
1917
echo "🚫 Skip hook: git commit --no-verify"
2018
exit 1
2119
fi

0 commit comments

Comments
 (0)