1# SPDX-License-Identifier: BSD-2-Clause 2 3# RCSid: 4# $Id: safe_eval.sh,v 1.20 2024/08/16 00:57:58 sjg Exp $ 5# 6# @(#) Copyright (c) 2023-2024 Simon J. Gerraty 7# 8# This file is provided in the hope that it will 9# be of use. There is absolutely NO WARRANTY. 10# Permission to copy, redistribute or otherwise 11# use this file is hereby granted provided that 12# the above copyright notice and this notice are 13# left intact. 14# 15# Please send copies of changes and bug-fixes to: 16# sjg@crufty.net 17 18_SAFE_EVAL_SH=: 19 20## 21# safe_set 22# 23# return a safe variable setting 24# any non-alphanumeric chars are replaced with '_' 25# 26safe_set() { 27 ${SED:-sed} 's/[ ]*#.*//;/^[A-Za-z_][A-Za-z0-9_]*=/!d;s;[^A-Za-z0-9_. "$,/=-];_;g' 28} 29 30## 31# safe_eval [file] 32# 33# eval variable assignments only from file 34# taking care to eliminate any shell meta chars 35# 36safe_eval() { 37 eval `cat "$@" | safe_set` 38} 39 40## 41# safe_eval_export [file] 42# 43# eval variable assignments only from file 44# taking care to eliminate any shell meta chars 45# export any variables thus set 46# 47safe_eval_export() { 48 eval `cat "$@" | safe_set | ${SED:-sed} 's/^\([^=]*\)=.*/&; export \1/'` 49} 50 51## 52# safe_dot file [...] 53# 54# feed all "file" that exist to safe_eval 55# 56safe_dot() { 57 eval ${local:-:} ef ex f rc 58 ef= 59 ex= 60 rc=1 61 while : 62 do 63 case "$1" in 64 --export) ex=_export; shift;; 65 *) break;; 66 esac 67 done 68 for f in "$@" 69 do 70 test -s "$f" -a -f "$f" || continue 71 : check for space or tab in "$f" 72 case "$f" in 73 *[[:space:]]*|*" "*|*" "*) # we cannot do this efficiently 74 dotted="$dotted $f" 75 safe_eval$ex "$f" 76 rc=$? 77 continue 78 ;; 79 esac 80 ef="${ef:+$ef }$f" 81 dotted="$dotted $f" 82 done 83 test -z "$ef" && return $rc 84 safe_eval$ex $ef 85 return 0 86} 87 88case /$0 in 89*/safe_eval*) 90 case "$1" in 91 dot|eval|set) op=safe_$1; shift; $op "$@";; 92 *) safe_dot "$@";; 93 esac 94 ;; 95esac 96