:1# RCSid:2# $Id: safe_eval.sh,v 1.25 2025/08/07 22:13:03 sjg Exp $3#4# @(#) Copyright (c) 2023-2024 Simon J. Gerraty5#6# SPDX-License-Identifier: BSD-2-Clause7#8# Please send copies of changes and bug-fixes to:9# [email protected]1011_SAFE_EVAL_SH=:1213# does local *actually* work?14local_works() {15local _fu16}1718if local_works > /dev/null 2>&1; then19_local=local20else21_local=:22fi2324##25# safe_set26#27# return a safe variable setting28# any non-alphanumeric chars are replaced with '_'29#30safe_set() {31${SED:-sed} 's/[ ]*#.*//;/^[A-Za-z_][A-Za-z0-9_]*=/!d;s;[^A-Za-z0-9_. "$,/=:+-];_;g'32}3334##35# safe_eval [file]36#37# eval variable assignments only from file38# taking care to eliminate any shell meta chars39#40safe_eval() {41eval `cat "$@" | safe_set`42}4344##45# safe_eval_export [file]46#47# eval variable assignments only from file48# taking care to eliminate any shell meta chars49# export any variables thus set50#51safe_eval_export() {52eval `cat "$@" | safe_set | ${SED:-sed} 's/^\([^=]*\)=.*/&; export \1/'`53}5455##56# safe_dot file [...]57#58# feed all "file" that exist to safe_eval59#60safe_dot() {61eval $_local ef ex f rc62ef=63ex=64rc=165while :66do67case "$1" in68--export) ex=_export; shift;;69*) break;;70esac71done72for f in "$@"73do74test -s "$f" -a -f "$f" || continue75: check for space or tab in "$f"76case "$f" in77*[[:space:]]*|*" "*|*" "*) # we cannot do this efficiently78dotted="$dotted $f"79safe_eval$ex "$f"80rc=$?81continue82;;83esac84ef="${ef:+$ef }$f"85dotted="$dotted $f"86done87test -z "$ef" && return $rc88safe_eval$ex $ef89return 090}9192case /$0 in93*/safe_eval*)94case "$1" in95dot|eval|set) op=safe_$1; shift; $op "$@";;96*) safe_dot "$@";;97esac98;;99esac100101102