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

Reply via email to