commit: bde4e730b46fe1dfb0bfefb3bb3932513d1dfc2d
Author: Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Feb 6 00:35:41 2026 +0000
Commit: Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Feb 6 01:45:15 2026 +0000
URL:
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=bde4e730
Employ braced parameter expansion consistently for eval
Several functions make use of the eval builtin in such a way that the
name of a given variable is dereferenced.
eval "val=\$$name"
However, to go about it in this way is unsafe for cases where positional
parameters are being dereferenced.
$ set -- 1 2 3 4 5 6 7 8 9 foo
$ name=10
$ eval "val=\$$name"
$ echo "val = $val" # foo is expected
val = 10
The correct way is as follows.
$ eval "val=\${$name}"
$ echo "val = $val"
val = foo
Consistently employ the latter style for the following three functions.
- str_between()
- deref()
- yesno()
Note that none of these functions were vulnerable prior to this commit.
As such, this can be considered as a defence-in-depth measure.
Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>
functions.sh | 4 ++--
functions/experimental.sh | 2 +-
functions/rc.sh | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/functions.sh b/functions.sh
index 06af1e1..529e629 100644
--- a/functions.sh
+++ b/functions.sh
@@ -183,9 +183,9 @@ deref()
elif ! eval "test \"\${$1+set}\""; then
false
elif [ "$#" -eq 1 ]; then
- eval "printf '%s\\n' \"\$$1\""
+ eval "printf '%s\\n' \"\${$1}\""
else
- eval "$2=\$$1"
+ eval "$2=\${$1}"
fi
}
diff --git a/functions/experimental.sh b/functions/experimental.sh
index 6b597ce..c1be482 100644
--- a/functions/experimental.sh
+++ b/functions/experimental.sh
@@ -206,7 +206,7 @@ str_between()
printf '%s\n' "$@" |
sort |
while IFS= read -r line; do
- eval "[ \"\${line}\" = \"\$$(( i += 1 ))\" ]" || return
+ eval "[ \"\${line}\" = \"\${$(( i += 1 ))}\" ]" ||
return
done
fi
}
diff --git a/functions/rc.sh b/functions/rc.sh
index 6e0dc10..2764e13 100644
--- a/functions/rc.sh
+++ b/functions/rc.sh
@@ -302,7 +302,7 @@ yesno()
else
# The value appears to be a legal variable name. Treat
# it as a name reference and try again, once only.
- eval "arg=\$$1"
+ eval "arg=\${$1}"
fi
done
_warn_for_args yesno "$@"