commit: 3de0f4f80587a58d93eb4d67dc0d536035cbd566
Author: Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon May 20 07:37:15 2024 +0000
Commit: Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon May 20 09:28:19 2024 +0000
URL:
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=3de0f4f8
Render argument checking more stringent; standardise diagnostics
Have esyslog(), is_older_than(), veend(), vewend() and yesno() die for
invalid arguments rather than issue a warning.
Have yesno() die if given no arguments, just as several other functions
already do.
Introduce a helper function named _throw_invalid_args() to assist. It
calls upon _print_args() to safely display any offending argument(s)
while also helping to standardise the diagnostics. To that end, the
diagnostic messages concerning wrong argument counts have been adjusted
to follow suit. Below are some examples.
test-functions: is_older_than: too few arguments (got 0, expected at least 2)
test-functions: is_older_than: too few arguments (got 1, expected at least 2)
test-functions: esyslog: too few arguments (got 0, expected at least 2)
test-functions: esyslog: too few arguments (got 1, expected at least 2)
test-functions: yesno: invalid argument: 'not-a-valid-nameref'
test-functions: yesno: invalid argument: '_"; set -- yes # code injection'
Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
functions.sh | 45 +++++++++++++++++++++++++++++++--------------
test-functions | 11 +++++------
2 files changed, 36 insertions(+), 20 deletions(-)
diff --git a/functions.sh b/functions.sh
index 100bd30..c82c229 100644
--- a/functions.sh
+++ b/functions.sh
@@ -216,7 +216,7 @@ eqatag() {
case ${arg} in
[!=/]*=?*)
if [ "${positional}" -eq 1 ]; then
- die "eqatag: invalid argument in
positional context -- ${arg}"
+ _throw_invalid_args eqatag "${arg}"
fi
set -- "$@" --arg "${arg%%=*}" "${arg#*=}"
;;
@@ -228,7 +228,7 @@ eqatag() {
set -- "$@" "${arg}"
;;
*)
- die "eqatag: invalid argument -- ${arg}"
+ _throw_invalid_args eqatag "${arg}"
esac
done
shift "${argc}"
@@ -263,8 +263,7 @@ esyslog()
local pri tag msg
if [ "$#" -lt 2 ]; then
- ewarn "Too few arguments for esyslog (got $#, expected at least
2)"
- return 1
+ die "esyslog: too few arguments (got $#, expected at least 2)"
elif yesno "${EINFO_LOG}" && hash logger 2>/dev/null; then
pri=$1
tag=$2
@@ -376,8 +375,7 @@ is_older_than()
local ref has_gfind
if [ "$#" -lt 2 ]; then
- ewarn "Too few arguments for is_older_than (got $#, expected at
least 2)"
- return 1
+ die "is_older_than: too few arguments (got $#, expected at
least 2)"
elif [ -e "$1" ]; then
ref=$1
else
@@ -424,7 +422,7 @@ veend()
if yesno "${EINFO_VERBOSE}"; then
GENFUN_CALLER=veend eend "$@"
elif [ "$#" -gt 0 ] && { ! is_int "$1" || [ "$1" -lt 0 ]; }; then
- ewarn "Invalid argument given to veend (the exit status code
must be an integer >= 0)"
+ _throw_invalid_args veend "$1"
else
return "$1"
fi
@@ -435,7 +433,7 @@ vewend()
if yesno "${EINFO_VERBOSE}"; then
GENFUN_CALLER=vewend ewend "$@"
elif [ "$#" -gt 0 ] && { ! is_int "$1" || [ "$1" -lt 0 ]; }; then
- ewarn "Invalid argument given to vewend (the exit status code
must be an integer >= 0)"
+ _throw_invalid_args vewend "$1"
else
return "$1"
fi
@@ -449,8 +447,14 @@ vewend()
#
yesno()
{
+ local arg
+
+ if [ "$#" -eq 0 ]; then
+ die "yesno: too few arguments (got $#, expected 1)"
+ fi
+ arg=$1
for _ in 1 2; do
- case $1 in
+ case ${arg} in
[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0|'')
return 1
;;
@@ -462,9 +466,9 @@ yesno()
else
# The value appears to be a legal variable name. Treat
# it as a name reference and try again, once only.
- eval "set -- \"\$$1\""
+ eval "arg=\$$1"
fi
- done || vewarn "Invalid argument given to yesno (expected a
boolean-like or a legal name)"
+ done || _throw_invalid_args yesno "$1"
return 1
}
@@ -481,9 +485,7 @@ _eend()
if [ "$#" -eq 0 ]; then
retval=0
elif ! is_int "$1" || [ "$1" -lt 0 ]; then
- ewarn "Invalid argument given to ${GENFUN_CALLER} (the exit
status code must be an integer >= 0)"
- retval=0
- msg=
+ _throw_invalid_args "${GENFUN_CALLER}" "$1"
else
retval=$1
shift
@@ -650,6 +652,21 @@ _print_args() {
EOF
}
+#
+# Prints a diganostic message concerning invalid function arguments then exits.
+# The first argument shall be taken as a function identifier. The remaining
+# arguments shall be safely rendered as a part of the diagnostic.
+#
+_throw_invalid_args()
+{
+ local ident plural
+
+ ident=$1
+ shift
+ [ "$#" -gt 1 ] && plural=s || plural=
+ die "${ident}: invalid argument${plural}: $(_print_args "$@")"
+}
+
#
# Determines whether the terminal on STDIN is able to report its dimensions.
# Upon success, the number of columns shall be stored in genfun_cols.
diff --git a/test-functions b/test-functions
index 7eb5981..40beded 100755
--- a/test-functions
+++ b/test-functions
@@ -196,7 +196,7 @@ test_is_older_than() {
callback() {
shift
test_description="is_older_than $(_print_args "$@")"
- is_older_than "$@"
+ ( is_older_than "$@" )
}
iterate_tests 4 "$@"
@@ -239,18 +239,17 @@ test_esyslog() {
logger() {
# esyslog() ignores empty messages. By overriding logger(1), it
# can be determined whether a message would have been logged.
- logged=$((logged + 1))
+ printf '1\n'
}
callback() {
should_log=$2
shift 2
- logged=0
test_description="esyslog $(_print_args "$@")"
- EINFO_LOG=1 esyslog "$@" 2>/dev/null
+ logged=$(EINFO_LOG=1 esyslog "$@")
case $? in
0)
- test "${logged}" -eq "${should_log}"
+ test "${logged:-0}" -eq "${should_log}"
;;
*)
return "$?"
@@ -393,7 +392,7 @@ test_yesno() {
callback() {
shift
test_description="yesno $(_print_args "$@")"
- yesno "$@"
+ ( yesno "$@" )
}
iterate_tests 3 "$@"