commit:     9bbf95a8fc7c280eb6cf323dc88b89e67293316a
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Feb 18 08:03:14 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Feb 19 16:14:06 2023 +0000
URL:        
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=9bbf95a8

Add and integrate an is_identifier() function

Break out the routine to check for a valid identifier (variable name)
from yesno() into its own function. It is designated as a public
function because a great many scripts exist that use eval in an
exceedingly dangerous fashion, essentially performing code injection.
This function could well benefit scripts of such a calibre.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/functions.sh b/functions.sh
index 7246179..beaef03 100644
--- a/functions.sh
+++ b/functions.sh
@@ -76,19 +76,11 @@ yesno()
                        [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
                                return 0
                esac
-               if [ "$_" -gt 1 ]; then
+               if [ "$_" -ne 1 ] || ! is_identifier "$1"; then
                        ! break
                else
-                       # Using eval can be very dangerous. Check whether the
-                       # value is a legitimate variable name before proceeding
-                       # to treat it as one.
-                       (
-                               LC_ALL=C
-                               case $1 in
-                                       ''|_|[[:digit:]]*|*[!_[:alnum:]]*) exit 
1
-                               esac
-                       ) || ! break
-                       # Treat the value as a nameref then try again.
+                       # The value appears to be a legal variable name. Treat
+                       # it as a name reference and try again, once only.
                        eval "set -- \"\$$1\""
                fi
        done || vewarn "Invalid argument given to yesno (expected a 
boolean-like or a legal name)"
@@ -471,6 +463,17 @@ _is_visible() {
        ! case $1 in *[[:graph:]]*) false ;; esac
 }
 
+#
+#   Determine whether the first operand is a valid identifier (variable name).
+#
+is_identifier()
+(
+       LC_ALL=C
+       case $1 in
+               ''|_|[[:digit:]]*|*[!_[:alnum:]]*) false
+       esac
+)
+
 # This is the main script, please add all functions above this point!
 # shellcheck disable=2034
 RC_GOT_FUNCTIONS="yes"

Reply via email to