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