tests/functional: Make our grep* helpers reject newlines in the query

Newlines behave like *OR*; not "and then".
This commit is contained in:
Robert Hensing 2024-07-16 01:41:22 +02:00
parent f2df3f0c6c
commit 644b97ce25
2 changed files with 21 additions and 3 deletions

View File

@ -336,13 +336,24 @@ callerPrefix() {
done done
} }
checkGrepArgs() {
local arg
for arg in "$@"; do
if [[ "$arg" != "${arg//$'\n'/_}" ]]; then
echo "$(callerPrefix)newline not allowed in arguments; grep would try each line individually as if connected by an OR operator" >&2
return -101
fi
done
}
# `grep -v` doesn't work well for exit codes. We want `!(exist line l. l # `grep -v` doesn't work well for exit codes. We want `!(exist line l. l
# matches)`. It gives us `exist line l. !(l matches)`. # matches)`. It gives us `exist line l. !(l matches)`.
# #
# `!` normally doesn't work well with `set -e`, but when we wrap in a # `!` normally doesn't work well with `set -e`, but when we wrap in a
# function it *does*. # function it *does*.
grepInverse() { grepInverse() {
! grep "$@" checkGrepArgs "$@" && \
! grep "$@"
} }
# A shorthand, `> /dev/null` is a bit noisy. # A shorthand, `> /dev/null` is a bit noisy.
@ -357,12 +368,14 @@ grepInverse() {
# the producer into the pipe. But rest assured we've seen it happen in # the producer into the pipe. But rest assured we've seen it happen in
# CI reliably. # CI reliably.
grepQuiet() { grepQuiet() {
grep "$@" > /dev/null checkGrepArgs "$@" && \
grep "$@" > /dev/null
} }
# The previous two, combined # The previous two, combined
grepQuietInverse() { grepQuietInverse() {
! grep "$@" > /dev/null checkGrepArgs "$@" && \
! grep "$@" > /dev/null
} }
# Return the number of arguments # Return the number of arguments

View File

@ -108,3 +108,8 @@ unset res
res=$(set -eu -o pipefail; echo foo | expect 1 grepQuietInverse foo | wc -c) res=$(set -eu -o pipefail; echo foo | expect 1 grepQuietInverse foo | wc -c)
(( res == 0 )) (( res == 0 ))
unset res unset res
# `grepQuiet` does not allow newlines in its arguments, because grep quietly
# treats them as multiple queries.
( echo foo; echo bar; ) | expectStderr -101 grepQuiet $'foo\nbar' \
| grepQuiet -E 'test-infra\.sh:[0-9]+: in call to grepQuiet: newline not allowed in arguments; grep would try each line individually as if connected by an OR operator'