Add test cases for safe_eval.sh

safe_set is the routine that does all the work.

In safe_set; if we replace one=`cmd arg` or two=$(cmd arg) add quotes
around the result eg. one="_cmd arg_"
Also lines containing `` or $() are too likely to result in syntax
errors, so just delete them.

Differential Revision:	https://reviews.freebsd.org/D56795
This commit is contained in:
Simon J. Gerraty
2026-05-18 10:51:18 -07:00
parent 32f854663d
commit 701d7be6e4
3 changed files with 78 additions and 2 deletions
+6 -1
View File
@@ -28,11 +28,16 @@ fi
# return a safe variable setting
# any non-alphanumeric chars other than those in "xtras"
# will be replaced with '_'
# Lines containing `` or $() are too likely to result in syntax errors
# so just delete them.
#
# "xtras" should be used with caution and cannot include ';'
#
safe_set() {
${SED:-sed} 's/^[ ]*//;s/[ ]*#.*//;s/^:.*//;/^[A-Za-z_][A-Za-z0-9_]*=/!d;s;[^A-Za-z0-9_. "'"$1"'$,/=:+-];_;g'
${SED:-sed} -e 's/^[ ]*//;s/[ ]*#.*//;s/^:.*//' \
-e '/`/d' -e '/\$(/d' \
-e '/^[A-Za-z_][A-Za-z0-9_]*=/!d;s;[^A-Za-z0-9_. "'"$1"'$,/=:+-];_;g;' \
-e '/=.*_.*[ ]/s,=\(.*\),="\1",;s,"",",g'
}
##
+7 -1
View File
@@ -1,3 +1,9 @@
ATF_TESTS_SH+= rc_subr_test
ATF_TESTS_SH+= rc_subr_test safe_eval_test
# allow running this as part of the build - in DIRDEPS_BUILD at least
.if ${.MAKE.LEVEL} > 0 && ${MACHINE:Nhost*} == ""
SAFE_EVAL:= ${_PARSEDIR:U${.PARSEDIR:tA}:H}/safe_eval.sh
.export SAFE_EVAL
.endif
.include <bsd.test.mk>
+65
View File
@@ -0,0 +1,65 @@
#-
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright 2026 Simon J Gerraty
#
atf_test_case safe_set_reject
safe_set_reject_head()
{
atf_set "descr" "Verify that safe_set rejects shell meta chars"
}
safe_set_reject_body()
{
__name="$(atf_get ident)"
__input=$(mktemp -t "${__name}.input")
cat <<'EOF' > "$__input"
: ignore=this
# ignore this too
# avoid # in the middle of a quoted value like:
# oops="this # will cause synatx error"
quoted="this and that"
simple=ok # trailing comments ignored
also=ok # leading white-space ignored
also_wik=ok
host=`hostname`' # backtics - delete line
os=$(uname -s) # $() - delete line
oops=one;hostname' # replace ; with _ so: one_hostname
regex="prefix[abc-]*" # []* replaced with _
EOF
__output=$(safe_set < "$__input" | tr '"\012' '\047;')
atf_check_equal "$__output" "quoted='this and that';simple=ok;also=ok;also_wik=ok;oops=one_hostname_;regex='prefix_abc-__';"
}
atf_test_case safe_set_xtras
safe_set_xtras_head()
{
atf_set "descr" "Verify that safe_set handles extra allowed chars"
}
safe_set_xtras_body()
{
__name="$(atf_get ident)"
__input=$(mktemp -t "${__name}.input")
cat <<'EOF' > "$__input"
: ignore=this
# ignore this too
regex="prefix[abc-]*"
EOF
__output=$(safe_set "[]*" < "$__input" | tr '"\012' '\047;')
atf_check_equal "$__output" "regex='prefix[abc-]*';"
}
atf_init_test_cases()
{
SAFE_EVAL=${SAFE_EVAL:-/libexec/safe_eval.sh}
. $SAFE_EVAL
atf_add_test_case safe_set_reject
atf_add_test_case safe_set_xtras
}