git: 47d669f10ea3 - main - bsdinstall: Encode dists to valid variable names in checksum script

From: Jessica Clarke <jrtc27_at_FreeBSD.org>
Date: Wed, 06 Dec 2023 21:40:46 UTC
The branch main has been updated by jrtc27:

URL: https://cgit.FreeBSD.org/src/commit/?id=47d669f10ea3eb92a3783376549728b42c9e22b9

commit 47d669f10ea3eb92a3783376549728b42c9e22b9
Author:     Jessica Clarke <jrtc27@FreeBSD.org>
AuthorDate: 2023-12-06 21:37:32 +0000
Commit:     Jessica Clarke <jrtc27@FreeBSD.org>
CommitDate: 2023-12-06 21:37:32 +0000

    bsdinstall: Encode dists to valid variable names in checksum script
    
    Currently we just strip the .txz of the dist name (and add a status_
    prefix) to get the shell variable name for its status, but this doesn't
    give a valid result for dists like base-dbg, kernel-dbg and lib32-dbg,
    or even kernel.KERNCONF (or, combining the two, kernel.KERNCONF-dbg). As
    a result, four things go wrong for such dists:
    
    1. If there is a dot and/or a dash in the name, writing to the variable
       fails and spits an error out on stderr to the log
    3. If there is a dot in the name before any dash, the syntax is always
       invalid, reading the variable fails, spits an error out on stderr to
       the log, the result is the empty string and that is interpreted as
       being 0%
    2. If there is a dash in the name before any dot, and there is a dist
       whose name is the substring up to that first dash, and it has already
       had its status written to, reading the variable instead reads that
       dist's variable and so the status of that dist is displayed instead
    3. If there is a dash in the name before any dot, and either there is
       not a dist whose name is the substring up to that first dash or there
       is such a dist but it has not already had its status written to,
       reading the varaible instead results in the substring after the first
       dash, including any additional string expansion syntax that follows
       (i.e. ${status_kernel-dbg:--11}, the expression used to read the
       variable, is interpreted as reading status_kernel with a default
       value of "dbg:--11")
    
    For example, in a default install with base, kernel, kernel-dbg and
    lib32, the following sequence of displays happens:
    
    1. base is In Progress, kernel is Pending, kernel-dbg is 0% (what shows
       for the garbage input "dbg:--11") and lib32 is Pending
    2. base is Passed, kernel is In Progress, kernel-dbg is In Progress
       (since kernel has now had its status written to) and lib32 is
       Pending
    3. base is Passed, kernel is Passed, kernel-dbg is Passed (again, since
       that is the status of kernel, despite that kernel-dbg is being
       verified at this point) and lib32 is Pending
    4. base is Passed, kernel is Passed, kernel-dbg is Passed and lib32 is
       In Progress
    
    Fix this with a crude encoding scheme. More special characters can
    easily be added if needed in future.
    
    Note that, prior to bsddialog being used (and thus for branches this is
    MFC'ed to where dialog is still used), the same problem existed but
    displayed slightly differently due to a combination of different default
    values and different behaviour for unintended inputs.
    
    Fixes:          b70047d41362 ("Add generation of an installation manifest containing SHA256 checksums as ...")
    MFC after:      1 week
---
 usr.sbin/bsdinstall/scripts/checksum | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/usr.sbin/bsdinstall/scripts/checksum b/usr.sbin/bsdinstall/scripts/checksum
index 376ba4261496..ee93cb342f25 100755
--- a/usr.sbin/bsdinstall/scripts/checksum
+++ b/usr.sbin/bsdinstall/scripts/checksum
@@ -30,14 +30,20 @@ test -f $BSDINSTALL_DISTDIR/MANIFEST || exit 0
 BSDCFG_SHARE="/usr/share/bsdconfig"
 . $BSDCFG_SHARE/common.subr || exit 1
 
+dist_to_statusvar()
+{
+	printf 'status_'
+	echo "$1" | sed 's/_/__/g;s/\./_dot_/g;s/-/_dash_/g'
+}
+
 percentage=0
 for dist in $DISTRIBUTIONS; do
-	distname=$(basename $dist .txz)
-	eval "status_$distname=-8"
+	statusvar=$(dist_to_statusvar $dist)
+	eval "$statusvar=-8"
 
 	items=""
 	for i in $DISTRIBUTIONS; do
-		items="$items $i `eval echo \\\${status_$(basename $i .txz):--11}`"
+		items="$items $i `eval echo \\\${$(dist_to_statusvar $i):--11}`"
 	done
 	bsddialog --backtitle "$OSNAME Installer" --title "Checksum Verification" \
 	    --mixedgauge "\nVerifying checksums of selected distributions.\n" \
@@ -57,13 +63,13 @@ for dist in $DISTRIBUTIONS; do
 	CK_VALID=$?
 	if [ $CK_VALID -le 1 ]; then
 		if [ $CK_VALID -eq 0 ]; then
-			eval "status_$distname=-3"
+			eval "$statusvar=-3"
 		else
-			eval "status_$distname=-7"
+			eval "$statusvar=-7"
 		fi
 		percentage=$(echo $percentage + 100/`echo $DISTRIBUTIONS | wc -w` | bc)
 	else
-		eval "status_$distname=-2"
+		eval "$statusvar=-2"
 		case $(/bin/freebsd-version -u) in
 		*-ALPHA*|*-CURRENT|*-STABLE|*-PRERELEASE)
 			bsddialog --backtitle "$OSNAME Installer" --title "Error" \