1
0
mirror of https://gitlab.com/fdroid/fdroidserver.git synced 2024-07-02 07:20:37 +02:00
fdroidserver/hooks/pre-commit
Hans-Christoph Steiner b851d49d24 shell=True is too dangerous to allow; there are unfiltered user inputs
There are all sorts of unfiltered user inputs like tag and branch names in
source repos.  If those names are fed into popen calls that use shell=True,
that opens up a wide range of exploits.  All core operations should never
use shell=True.
2018-01-26 10:18:41 +01:00

137 lines
3.4 KiB
Bash
Executable File

#!/bin/bash
#
# Simple pre-commit hook to check that there are no errors in the fdroidserver
# source files.
# Redirect output to stderr.
exec 1>&2
files=`git diff-index --cached HEAD 2>&1 | sed 's/^:.* //' | uniq | cut -b100-500`
if [ -z "$files" ]; then
PY_FILES="fdroid makebuildserver setup.py examples/*.py buildserver/*.py fdroidserver/*.py"
PY_TEST_FILES="tests/*.TestCase"
SH_FILES="hooks/pre-commit"
BASH_FILES="jenkins-build-all jenkins-setup-build-environment jenkins-test completion/bash-completion buildserver/provision-*"
RB_FILES="buildserver/Vagrantfile"
else
# if actually committing right now, then only run on the files
# that are going to be committed at this moment
PY_FILES=
PY_TEST_FILES=
SH_FILES=
BASH_FILES=
RB_FILES=
for f in $files; do
test -e $f || continue
case $f in
*.py)
PY_FILES+=" $f"
;;
*.TestCase)
PY_TEST_FILES+=" $f"
;;
*.rb)
RB_FILES+=" $f"
;;
*)
if head -1 $f | grep '^#!/bin/sh' > /dev/null 2>&1; then
SH_FILES+=" $f"
elif head -1 $f | grep '^#!/bin/bash' > /dev/null 2>&1; then
BASH_FILES+=" $f"
elif head -1 $f | grep '^#!.*python' > /dev/null 2>&1; then
PY_FILES+=" $f"
fi
;;
esac
done
fi
# We ignore the following PEP8 warnings
# * E123: closing bracket does not match indentation of opening bracket's line
# - Broken if multiple indentation levels start on a single line
# * E501: line too long (82 > 79 characters)
# - Recommended for readability but not enforced
# - Some lines are awkward to wrap around a char limit
# * W503: line break before binary operator
# - Quite pedantic
PEP8_IGNORE="E123,E501,W503"
err() {
echo >&2 ERROR: "$@"
exit 1
}
warn() {
echo >&2 WARNING: "$@"
}
cmd_exists() {
command -v $1 1>/dev/null
}
find_command() {
for name in $@; do
for suff in "3" "-3" "-python3" ""; do
cmd=${name}${suff}
if cmd_exists $cmd; then
echo $cmd
return 0
fi
done
done
warn "$1 is not installed, using dummy placeholder!"
echo :
}
DASH=$(find_command dash)
PYFLAKES=$(find_command pyflakes)
PEP8=$(find_command pycodestyle pep8)
RUBY=$(find_command ruby)
if [ "$PY_FILES $PY_TEST_FILES" != " " ]; then
if ! $PYFLAKES $PY_FILES $PY_TEST_FILES; then
err "pyflakes tests failed!"
fi
fi
if [ "$PY_FILES" != "" ]; then
if ! $PEP8 --ignore=$PEP8_IGNORE $PY_FILES; then
err "pep8 tests failed!"
fi
fi
# The tests use a little hack in order to cleanly import the fdroidserver
# package locally like a regular package. pep8 doesn't see that, so this
# makes pep8 skip E402 on the test files that need that hack.
if [ "$PY_TEST_FILES" != "" ]; then
if ! $PEP8 --ignore=$PEP8_IGNORE,E402 $PY_TEST_FILES; then
err "pep8 tests failed!"
fi
fi
for f in $SH_FILES; do
if ! $DASH -n $f; then
err "dash tests failed!"
fi
done
for f in $BASH_FILES; do
if ! bash -n $f; then
err "bash tests failed!"
fi
done
for f in $RB_FILES; do
if ! $RUBY -c $f 1>/dev/null; then
err "ruby tests failed!"
fi
done
if grep --line-number 'shell=True' fdroidserver/[a-ce-z]*.py; then
err "shell=True is too dangerous, there are unfiltered user inputs!"
fi
exit 0