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.
This commit is contained in:
Avi Halachmi (:avih) 2024-12-04 13:59:33 +02:00
parent ab6e750bd5
commit 9289c6c5e0

24
configure vendored
View file

@ -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