From 9289c6c5e0da13d4089d48c4912ec2dbb7b1053d Mon Sep 17 00:00:00 2001 From: "Avi Halachmi (:avih)" Date: Wed, 4 Dec 2024 13:59:33 +0200 Subject: [PATCH] configure: confvars: warn/error on bad key or value $confvars is not supposed to hold the same key more than once, and spaces in values won't be parsed correctly. Additionally, it's later iterated using shell IFS-split - which will also apply globs. We now abort if the value IFS-splits badly (spaces/glob/empty). We now warn on duplicates, but still accept them like before. Example duplicate: --enable-static --disable-static Example spaces: --config-foo="bar baz" Example glob: --config-foo=" * " Note that globs currently already expand at eval opt=\"$opt\" before we get a chance to test it (but we still detect the spaces). See commit message of 21272067 (boilerplate var=..) about removing it. These tests are also performed on values which configure itself adds, but currently there are no issues with those. Also, default_conf() now uses confvars_has, which fixes the following: - False-positive if the key is a substring of existing key or value. - Incorrect test if the value contains '=' or sh pattern chars *?[] . No-op, because current default_conf calls don't have such issues. --- configure | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 3d7edab6..f0a3044a 100755 --- a/configure +++ b/configure @@ -70,8 +70,26 @@ assign_opt() { eval ${1#--}=\$2 # no risk of IFS/glob in [OPT]NAME } +# succeed if $1 doesn't IFS-split funny (globs, spaces, ...) +good_split() { + set -- "$1" $1 + test $# = 2 && test "$1" = "$2" +} + +# $1: NAME[=VALUE] succeed if confvars has NAME or NAME=* element +confvars_has() { + ! case " $confvars " in *" ${1%%=*} "* | *" ${1%%=*}="*) + false + esac +} + +# [multiple] NAME or NAME=VAL confvars_set() { - confvars="$confvars $*" + for cv; do + good_split "$cv" || { echo "configure: ERROR: bad config '$cv'"; exit 1; } + confvars_has "$cv" && echo "configure: WARNING: duplicate config '$cv'" + confvars="$confvars $cv" + done } for opt do @@ -221,9 +239,9 @@ default() # set variable unless already set and not empty test -n "$2" && eval : \${$1:=\$2} # ': ${foo:=$2}' } -default_conf() # add to confvars unless already present +default_conf() # add one config to confvars unless already present { - test "${confvars%${1%=*}*}" = "${confvars}" && confvars_set "$1" + confvars_has "$1" || confvars_set "$1" } if test -z "${source_path#.}" ; then