From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <gentoo-commits+bounces-1488252-garchives=archives.gentoo.org@lists.gentoo.org>
Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (2048 bits))
	(No client certificate requested)
	by finch.gentoo.org (Postfix) with ESMTPS id EBFE315800F
	for <garchives@archives.gentoo.org>; Sun, 19 Feb 2023 16:14:36 +0000 (UTC)
Received: from pigeon.gentoo.org (localhost [127.0.0.1])
	by pigeon.gentoo.org (Postfix) with SMTP id 26454E08CD;
	Sun, 19 Feb 2023 16:14:36 +0000 (UTC)
Received: from smtp.gentoo.org (dev.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (4096 bits))
	(No client certificate requested)
	by pigeon.gentoo.org (Postfix) with ESMTPS id 123F2E08CD
	for <gentoo-commits@lists.gentoo.org>; Sun, 19 Feb 2023 16:14:36 +0000 (UTC)
Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (4096 bits))
	(No client certificate requested)
	by smtp.gentoo.org (Postfix) with ESMTPS id 4BE05340C72
	for <gentoo-commits@lists.gentoo.org>; Sun, 19 Feb 2023 16:14:35 +0000 (UTC)
Received: from localhost.localdomain (localhost [IPv6:::1])
	by oystercatcher.gentoo.org (Postfix) with ESMTP id 66ABA8BA
	for <gentoo-commits@lists.gentoo.org>; Sun, 19 Feb 2023 16:14:32 +0000 (UTC)
From: "Sam James" <sam@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Content-Transfer-Encoding: 8bit
Content-type: text/plain; charset=UTF-8
Reply-To: gentoo-dev@lists.gentoo.org, "Sam James" <sam@gentoo.org>
Message-ID: <1676823246.9bbf95a8fc7c280eb6cf323dc88b89e67293316a.sam@gentoo>
Subject: [gentoo-commits] proj/gentoo-functions:master commit in: /
X-VCS-Repository: proj/gentoo-functions
X-VCS-Files: functions.sh
X-VCS-Directories: /
X-VCS-Committer: sam
X-VCS-Committer-Name: Sam James
X-VCS-Revision: 9bbf95a8fc7c280eb6cf323dc88b89e67293316a
X-VCS-Branch: master
Date: Sun, 19 Feb 2023 16:14:32 +0000 (UTC)
Precedence: bulk
List-Post: <mailto:gentoo-commits@lists.gentoo.org>
List-Help: <mailto:gentoo-commits+help@lists.gentoo.org>
List-Unsubscribe: <mailto:gentoo-commits+unsubscribe@lists.gentoo.org>
List-Subscribe: <mailto:gentoo-commits+subscribe@lists.gentoo.org>
List-Id: Gentoo Linux mail <gentoo-commits.gentoo.org>
X-BeenThere: gentoo-commits@lists.gentoo.org
X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply
X-Archives-Salt: 74acdb58-0c43-4d77-9655-e28cc6a5f82b
X-Archives-Hash: 221d11230b2c46da2ce3f04c922f3229

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"