git: 7c75c96d176f - main - safe_eval.sh: safe_set_var avoid positional args
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 11 Oct 2026 18:13:09 UTC
The branch main has been updated by sjg:
URL: https://cgit.FreeBSD.org/src/commit/?id=7c75c96d176f600c7d17cb4652a1e655b44b2943
commit 7c75c96d176f600c7d17cb4652a1e655b44b2943
Author: Simon J. Gerraty <sjg@FreeBSD.org>
AuthorDate: 2026-10-11 18:12:59 +0000
Commit: Simon J. Gerraty <sjg@FreeBSD.org>
CommitDate: 2026-10-11 18:12:59 +0000
safe_eval.sh: safe_set_var avoid positional args
Use options to set ssv_{allow,only,extra}
Improve the documentation.
Add a test harness for safe_set_var.
---
libexec/rc/safe_eval.sh | 90 ++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 74 insertions(+), 16 deletions(-)
diff --git a/libexec/rc/safe_eval.sh b/libexec/rc/safe_eval.sh
index 940465581c62..597c9e79ef9e 100644
--- a/libexec/rc/safe_eval.sh
+++ b/libexec/rc/safe_eval.sh
@@ -1,6 +1,6 @@
:
# RCSid:
-# $Id: safe_eval.sh,v 1.32 2026/10/11 06:02:40 sjg Exp $
+# $Id: safe_eval.sh,v 1.34 2026/10/11 18:08:28 sjg Exp $
#
# @(#) Copyright (c) 2023-2026 Simon J. Gerraty
#
@@ -23,26 +23,53 @@ else
fi
##
-# safe_set_var "var=val" ["allowed_vars" ["only_chars" ["extra_chars"]]]
+# safe_set_var ["options"] "var=val"
+#
+# Useful for processing command line input like 'var=val'.
#
-# Useful for processing command line input like 'var=val'
# We perform a number of sanity checks similar to safe_set.
# We set ssv_var=var and ssv_val=val so that caller can produce
-# error messages if desired. ssv_var or ssv_val will be set to
-# 'invalid' if they fail the relevant checks.
+# error messages if desired.
+# To be safe, ssv_var and/or ssv_val will be set to 'invalid'
+# if they fail the relevant checks.
+#
+# Options:
+#
+# -a "allow"
+# list of allowed variable names.
+#
+# -o "only_chars"
+# white-list of acceptable chars in "val"
+# default is 'A-Za-z0-9_ ,/=:+-'.
+#
+# -x "extra_chars"
+# eXtra chars to add to white-list for "val".
+#
# 1. if "var" contains anything but 'A-Za-z0-9_' or matches 'ssv_*'
-# we set ssv_var=invalid and return 1
+# we set ssv_var=invalid and return 1.
+#
# 2. if "val" contains anything not in the combined set of
# "only_chars" and "extra_chars" we will set ssv_val=invalid
-# and return 2
-# 3. if "allowed_vars" and "var" is not a member we return 3
-# If "only_chars" is not provided we use 'A-Za-z0-9_ ,/=:+-'
-# similar to save_set.
-# If we pass all that, we eval "var=val" and return 0
+# and return 2.
+#
+# 3. if "allow" is set and "var" is not a member we return 3.
+#
+# If we pass all that, we eval "var=val" and return 0.
#
safe_set_var() {
- eval $_local ssv_rc
+ eval $_local ssv_allow ssv_extra ssv_only ssv_rc
+ ssv_only="A-Za-z0-9_. \$,/=:+-"
ssv_rc=
+
+ while :
+ do
+ case "$1" in
+ -a) ssv_allow="$2"; shift 2;;
+ -o) ssv_only="$2"; shift 2;;
+ -x) ssv_extra="$2"; shift 2;;
+ *) break;;
+ esac
+ done
if ${isPOSIX_SHELL:-false}; then
ssv_var="${1%%=*}"
ssv_val="${1#*=}"
@@ -59,13 +86,13 @@ safe_set_var() {
esac
: is ssv_val ok - "$ssv_val"
case "$ssv_val" in
- *[!${3:-A-Za-z0-9_. \$,/=:+-}$4]*)
+ *[!$ssv_only$ssv_extra]*)
ssv_val=invalid
ssv_rc=${ssv_rc:-2}
;;
esac
: is $ssv_var is allowed - "${2:-$ssv_var}"
- case " ${2:-$ssv_var} " in
+ case " ${ssv_allow:-$ssv_var} " in
*" $ssv_var "*) ;;
*) ssv_rc=${ssv_rc:-3};;
esac
@@ -87,7 +114,7 @@ safe_set_var() {
# so just delete them.
#
# "xtras" should be used with caution and cannot include ';'
-#
+#
safe_set() {
${SED:-sed} -e 's/^[ ]*//;s/[ ]*#.*//;s/^:.*//' \
-e '/`/d' -e '/\$(/d' \
@@ -153,11 +180,42 @@ safe_dot() {
return 0
}
+# for testing
case /$0 in
*/safe_eval*)
case "$1" in
dot|eval|set) op=safe_$1; shift; $op "$@";;
- *) safe_dot "$@";;
+ set_var)
+ shift
+ allow=
+ only=
+ extra=
+
+ while :
+ do
+ : 1="$1"
+ case "$1" in
+ -a) allow="$2"; shift 2;;
+ -o) only="$2"; shift 2;;
+ -x) extra="$2"; shift 2;;
+ *=*)
+ if safe_set_var ${allow:+-a "$allow"} ${only:+-o "$only"} \
+ ${extra:+-x "$extra"} "$1"; then
+ echo $ssv_var=$ssv_val
+ else
+ case $? in
+ 1) echo invalid variable;;
+ 2) echo invalid value for $ssv_var;;
+ 3) echo denied $ssv_var;;
+ esac
+ fi
+ shift
+ ;;
+ *) break;;
+ esac
+ done
+ ;;
+ *) safe_dot "$@";;
esac
;;
esac