From ec9ec4ad367f494165ced611af6b2641e8cb2472 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Sun, 6 Nov 2011 19:13:43 -0500 Subject: functions: implement a environment file parser This adds a 'parse_envfile' function that reads files such as /etc/locale.conf and /etc/vconsole.conf without sourcing them as bash logic. Several benefits are realized from this: - Impossible to execute arbitrary code - Bad syntax won't prevent the entire file from being read - Possible to limit what variables are allowed Signed-off-by: Dave Reisner --- functions | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) (limited to 'functions') diff --git a/functions b/functions index ce664ed..387f2af 100644 --- a/functions +++ b/functions @@ -9,6 +9,8 @@ localevars=(LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION LC_ALL) +vconsolevars=(KEYMAP KEYMAP_TOGGLE FONT FONT_MAP FONT_UNIMAP) + if [[ $1 == "start" ]]; then if [[ $STARTING ]]; then echo "A daemon is starting another daemon, this is unlikely to work as intended." @@ -70,12 +72,56 @@ unset TZ # sanitize the locale settins unset "${localevars[@]}" +parse_envfile() { + local file=$1 validkeys=${@:2} ret=0 lineno=0 key= val= + + if [[ -z $file ]]; then + printf "error: no environment file specified\n" + return 1 + fi + + if [[ ! -f $file ]]; then + printf "error: cannot parse \`%s': No such file or directory\n" "$file" + return 1 + fi + + if [[ ! -r $file ]]; then + printf "error: cannot read \`%s': Permission denied\n" "$file" + return 1 + fi + + while IFS='=' read -r key val; do + (( ++lineno )) + + # trim whitespace, avoiding usage of a tempfile + key=$(echo "$1" | { read -r val; echo "$val"; }) + val=$(echo "$1" | { read -r val; echo "$val"; }) + + [[ $key ]] || continue + + if [[ -z $val ]]; then + printf "error: found key \`%s' without value on line %s of %s\n" \ + "$key" "$lineno" "$file" + (( ++ret )) + continue + fi + + # ignore invalid keys if we have a list of valid ones + if (( ${#validkeys[*]} )); then + in_array "$key" "${validkeys[@]}" || continue + fi + + export "$key=$val" || (( ++ret )) + done <"$file" + + return $ret +} + if [[ $DAEMON_LOCALE = [yY][eE][sS] ]]; then LANG=${LOCALE:-C} if [[ -r /etc/locale.conf ]]; then - . /etc/locale.conf + parse_envfile /etc/locale.conf "${localevars[@]}" fi - export "${localevars[@]}" else export LANG=C fi -- cgit v1.2.3