Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

serialize filewise args to 'grep' and 'git grep' #153

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 57 additions & 2 deletions git-secrets
Original file line number Diff line number Diff line change
Expand Up @@ -113,16 +113,71 @@ git_grep() {
local files=("${@}") combined_patterns=$(load_combined_patterns)

[ -z "${combined_patterns}" ] && return 1
GREP_OPTIONS= LC_ALL=C git grep -nwHEI ${options} "${combined_patterns}" -- "${files[@]}"

if [ ${#files[@]} -eq 0 ]; then
GREP_OPTIONS= LC_ALL=C git grep -nwHEI ${options} "${combined_patterns}"
return $?
fi

# let xargs watch for system limit on arg count for us. xargs returns 123 if
# any call returned 1, but we care that all calls returned 1, so invert the
# output - xargs will return 0 if every call returned 0
printf "%s\n" "${files[@]}" |
GREP_OPTIONS= LC_ALL=C xargs -P "$(nproc)" -d'\n' sh -c \
nasamuffin marked this conversation as resolved.
Show resolved Hide resolved
'git grep "$@"
rc=$?
case $rc in
0) exit 1 ;;
1) exit 0 ;;
*) exit 255 ;;
esac' - \
-nwHEI "${options}" "${combined_patterns}" --
status=$?
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May want this to be local. Or:

case $? in
  0) ...


# convert the xargs-ified return code to what grep would have returned
case $status in
0) return 1 ;;
123) return 0 ;;
*) return 2 ;;
esac
}

# Performs a regular grep, taking into account patterns and recursion.
# Note: this function returns 1 on success, 0 on error.
regular_grep() {
local files=("${@}") patterns=$(load_patterns) action='skip'
local status=0
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

likewise, can avoid this temporary variable by using $? directly

[ -z "${patterns}" ] && return 1
[ ${RECURSIVE} -eq 1 ] && action="recurse"
GREP_OPTIONS= LC_ALL=C grep -d "${action}" -nwHEI "${patterns}" "${files[@]}"

if [ "${#files[@]}" -eq 1 ] && [ "${files[0]}" = "-" ]; then
GREP_OPTIONS= LC_ALL=C grep -d "${action}" -nwHEI "${patterns}" -
return $?
fi

# let xargs watch for system limit on arg count for us.
# massage output so that xargs returns:
# 0 if all calls succeeded ("no match")
# 123 if any call failed with status 1-128 ("found a match")
# 124 if any call failed with status 255 ("error")
printf "%s\n" "${files[@]}" |
GREP_OPTIONS= LC_ALL=C xargs -P "$(nproc)" -d'\n' sh -c \
'grep "$@"
rc=$?
case $rc in
0) exit 1 ;;
1) exit 0 ;;
*) exit 255 ;;
esac' - \
-d "${action}" -nwHEI "${patterns}"
status=$?

# convert the xargs-ified return code to what grep would have returned
case $status in
0) return 1 ;;
123) return 0 ;;
*) return 2 ;;
esac
}

# Process the given status ($1) and output variables ($2).
Expand Down
17 changes: 17 additions & 0 deletions test/pre-commit.bats
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,20 @@ load test_helper
[ "${lines[1]}" == "failure1.txt:1:another line... forbidden" ]
[ "${lines[2]}" == "failure2.txt:1:me" ]
}

@test "Runs safely with args beyond the system argument length limit" {
setup_good_repo
repo_run git-secrets --install $TEST_REPO
cd $TEST_REPO

FILENAME_LENGTH="$(getconf NAME_MAX .)"
(( FILE_COUNT = ( "$(getconf ARG_MAX)" / "$FILENAME_LENGTH" ) + 1 ))

for (( i = 0; i < "$FILE_COUNT"; i++ )); do
>"$(printf "%0${FILENAME_LENGTH}d" "$i")"
done

run git add .
run git commit -m 'This is fine'
[ $status -eq 0 ]
}
5 changes: 5 additions & 0 deletions test/test_helper.bash
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#!/bin/bash
# Disallow any system-level git-secret pattern configs
export GIT_CONFIG_NOSYSTEM="true"
export TEST_REPO="$BATS_TMPDIR/test-repo"
export TEMP_HOME="$BATS_TMPDIR/home"
export TEMPLATE_DIR="${BATS_TMPDIR}/template"
Expand Down Expand Up @@ -31,6 +33,9 @@ setup_repo() {
mkdir -p $TEST_REPO
cd $TEST_REPO
git init --initial-branch=master
# Uninstall any hooks present in the system template which could interfere
# with git-secrets
rm -fr .git/hooks/*
git config --local --add secrets.patterns '@todo'
git config --local --add secrets.patterns 'forbidden|me'
git config --local --add secrets.patterns '#hash'
Expand Down