aboutsummaryrefslogtreecommitdiff
path: root/libexec/rc/safe_eval.sh
diff options
context:
space:
mode:
Diffstat (limited to 'libexec/rc/safe_eval.sh')
-rw-r--r--libexec/rc/safe_eval.sh100
1 files changed, 100 insertions, 0 deletions
diff --git a/libexec/rc/safe_eval.sh b/libexec/rc/safe_eval.sh
new file mode 100644
index 000000000000..6c23b4c98218
--- /dev/null
+++ b/libexec/rc/safe_eval.sh
@@ -0,0 +1,100 @@
+:
+# RCSid:
+# $Id: safe_eval.sh,v 1.25 2025/08/07 22:13:03 sjg Exp $
+#
+# @(#) Copyright (c) 2023-2024 Simon J. Gerraty
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Please send copies of changes and bug-fixes to:
+# sjg@crufty.net
+
+_SAFE_EVAL_SH=:
+
+# does local *actually* work?
+local_works() {
+ local _fu
+}
+
+if local_works > /dev/null 2>&1; then
+ _local=local
+else
+ _local=:
+fi
+
+##
+# safe_set
+#
+# return a safe variable setting
+# any non-alphanumeric chars are replaced with '_'
+#
+safe_set() {
+ ${SED:-sed} 's/[ ]*#.*//;/^[A-Za-z_][A-Za-z0-9_]*=/!d;s;[^A-Za-z0-9_. "$,/=:+-];_;g'
+}
+
+##
+# safe_eval [file]
+#
+# eval variable assignments only from file
+# taking care to eliminate any shell meta chars
+#
+safe_eval() {
+ eval `cat "$@" | safe_set`
+}
+
+##
+# safe_eval_export [file]
+#
+# eval variable assignments only from file
+# taking care to eliminate any shell meta chars
+# export any variables thus set
+#
+safe_eval_export() {
+ eval `cat "$@" | safe_set | ${SED:-sed} 's/^\([^=]*\)=.*/&; export \1/'`
+}
+
+##
+# safe_dot file [...]
+#
+# feed all "file" that exist to safe_eval
+#
+safe_dot() {
+ eval $_local ef ex f rc
+ ef=
+ ex=
+ rc=1
+ while :
+ do
+ case "$1" in
+ --export) ex=_export; shift;;
+ *) break;;
+ esac
+ done
+ for f in "$@"
+ do
+ test -s "$f" -a -f "$f" || continue
+ : check for space or tab in "$f"
+ case "$f" in
+ *[[:space:]]*|*" "*|*" "*) # we cannot do this efficiently
+ dotted="$dotted $f"
+ safe_eval$ex "$f"
+ rc=$?
+ continue
+ ;;
+ esac
+ ef="${ef:+$ef }$f"
+ dotted="$dotted $f"
+ done
+ test -z "$ef" && return $rc
+ safe_eval$ex $ef
+ return 0
+}
+
+case /$0 in
+*/safe_eval*)
+ case "$1" in
+ dot|eval|set) op=safe_$1; shift; $op "$@";;
+ *) safe_dot "$@";;
+ esac
+ ;;
+esac