The branch main has been updated by sjg: URL: https://cgit.FreeBSD.org/src/commit/?id=701d7be6e4a9a145700fdee5c038470b355a0e05
commit 701d7be6e4a9a145700fdee5c038470b355a0e05 Author: Simon J. Gerraty <[email protected]> AuthorDate: 2026-05-18 17:51:18 +0000 Commit: Simon J. Gerraty <[email protected]> CommitDate: 2026-05-18 17:51:18 +0000 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 --- libexec/rc/safe_eval.sh | 7 +++- libexec/rc/tests/Makefile | 8 ++++- libexec/rc/tests/safe_eval_test.sh | 65 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/libexec/rc/safe_eval.sh b/libexec/rc/safe_eval.sh index 3b3241ae821d..eb1698472624 100644 --- a/libexec/rc/safe_eval.sh +++ b/libexec/rc/safe_eval.sh @@ -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' } ## diff --git a/libexec/rc/tests/Makefile b/libexec/rc/tests/Makefile index c44c6db90b77..3a6eafea292d 100644 --- a/libexec/rc/tests/Makefile +++ b/libexec/rc/tests/Makefile @@ -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> diff --git a/libexec/rc/tests/safe_eval_test.sh b/libexec/rc/tests/safe_eval_test.sh new file mode 100644 index 000000000000..a0f3a2784098 --- /dev/null +++ b/libexec/rc/tests/safe_eval_test.sh @@ -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 +}
