From 8d18d8f745b6afae88c896f432b2cfd81c6e134a Mon Sep 17 00:00:00 2001
From: nl6720 <nl6720@gmail.com>
Date: Tue, 24 Aug 2021 18:57:27 +0300
Subject: [PATCH 1/3] mkarchiso: fix unbound variable errors in
 _validate_options

$pkg_list_from_file and $bootstrap_pkg_list_from_file are arrays, they must be referenced as such. Fixes https://bugs.archlinux.org/task/71852.

Remove quotes from arithmetic expressions.
---
 archiso/mkarchiso | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/archiso/mkarchiso b/archiso/mkarchiso
index a77d3d9..e2b6674 100755
--- a/archiso/mkarchiso
+++ b/archiso/mkarchiso
@@ -978,7 +978,7 @@ _validate_options() {
     if [[ -e "${packages}" ]]; then
         mapfile -t pkg_list_from_file < <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${packages}")
         pkg_list+=("${pkg_list_from_file[@]}")
-        if (( ${#pkg_list_from_file} < 1 )); then
+        if (( ${#pkg_list_from_file[@]} < 1 )); then
             (( validation_error=validation_error+1 ))
             _msg_error "No package specified in '${packages}'." 0
         fi
@@ -993,7 +993,7 @@ _validate_options() {
             mapfile -t bootstrap_pkg_list_from_file < \
                 <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${bootstrap_packages}")
             bootstrap_pkg_list+=("${bootstrap_pkg_list_from_file[@]}")
-            if (( ${#bootstrap_pkg_list_from_file} < 1 )); then
+            if (( ${#bootstrap_pkg_list_from_file[@]} < 1 )); then
                 (( validation_error=validation_error+1 ))
                 _msg_error "No package specified in '${bootstrap_packages}'." 0
             fi
@@ -1014,7 +1014,7 @@ _validate_options() {
         done
         cert_list=("${_override_cert_list[@]}")
         # Check if there are at least two certificate files
-        if (( "${#cert_list[@]}" < 2 )); then
+        if (( ${#cert_list[@]} < 2 )); then
             (( validation_error=validation_error+1 ))
             _msg_error "Two certificates are required for codesigning, but '${cert_list[*]}' is provided." 0
         fi
@@ -1074,7 +1074,7 @@ _validate_options() {
 _set_overrides() {
     # Set variables that have command line overrides
     [[ ! -v override_buildmodes ]] || buildmodes=("${override_buildmodes[@]}")
-    if (( "${#buildmodes[@]}" < 1 )); then
+    if (( ${#buildmodes[@]} < 1 )); then
         buildmodes+=('iso')
     fi
     if [[ -v override_work_dir ]]; then

From f3959d6ef054af629d162052fd42f3d9fb2512dd Mon Sep 17 00:00:00 2001
From: nl6720 <nl6720@gmail.com>
Date: Tue, 24 Aug 2021 19:19:20 +0300
Subject: [PATCH 2/3] mkarchiso: split out build mode specific checks from
 _validate_options to _validate_requirements_buildmode_*

The bootstrap build mode does not use packages.${arch}, ${bootmodes[@]} or $airootfs_image_type so there's no need to validate them.
Requirements common to iso and netboot are checked with the _validate_common_requirements_buildmode_iso_netboot function.

Fixes #149.

* Rename _validate_requirements_buildmode_all to _validate_common_requirements_buildmode_all to prevent potential conflicts since we are using _validate_requirements_buildmode_${_buildmode} to run the functions.
* Improve searching in an array. See https://stackoverflow.com/a/15394738.
---
 archiso/mkarchiso | 163 ++++++++++++++++++++++++----------------------
 1 file changed, 86 insertions(+), 77 deletions(-)

diff --git a/archiso/mkarchiso b/archiso/mkarchiso
index e2b6674..fb601c3 100755
--- a/archiso/mkarchiso
+++ b/archiso/mkarchiso
@@ -747,7 +747,7 @@ _validate_requirements_airootfs_image_type_erofs() {
     fi
 }
 
-_validate_requirements_buildmode_all() {
+_validate_common_requirements_buildmode_all() {
     if ! command -v pacman &> /dev/null; then
         (( validation_error=validation_error+1 ))
         _msg_error "Validating build mode '${_buildmode}': pacman is not available on this host. Install 'pacman'!" 0
@@ -763,15 +763,76 @@ _validate_requirements_buildmode_all() {
 }
 
 _validate_requirements_buildmode_bootstrap() {
-    _validate_requirements_buildmode_all
+    local bootstrap_pkg_list_from_file=()
+
+    # Check if packages for the bootstrap image are specified
+    if [[ -e "${bootstrap_packages}" ]]; then
+        mapfile -t bootstrap_pkg_list_from_file < \
+            <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${bootstrap_packages}")
+        bootstrap_pkg_list+=("${bootstrap_pkg_list_from_file[@]}")
+        if (( ${#bootstrap_pkg_list_from_file[@]} < 1 )); then
+            (( validation_error=validation_error+1 ))
+            _msg_error "No package specified in '${bootstrap_packages}'." 0
+        fi
+    else
+        (( validation_error=validation_error+1 ))
+        _msg_error "Bootstrap packages file '${bootstrap_packages}' does not exist." 0
+    fi
+
+    _validate_common_requirements_buildmode_all
     if ! command -v bsdtar &> /dev/null; then
         (( validation_error=validation_error+1 ))
         _msg_error "Validating build mode '${_buildmode}': bsdtar is not available on this host. Install 'libarchive'!" 0
     fi
 }
 
+_validate_common_requirements_buildmode_iso_netboot() {
+    local bootmode
+    local pkg_list_from_file=()
+
+    # Check if the package list file exists and read packages from it
+    if [[ -e "${packages}" ]]; then
+        mapfile -t pkg_list_from_file < <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${packages}")
+        pkg_list+=("${pkg_list_from_file[@]}")
+        if (( ${#pkg_list_from_file[@]} < 1 )); then
+            (( validation_error=validation_error+1 ))
+            _msg_error "No package specified in '${packages}'." 0
+        fi
+    else
+        (( validation_error=validation_error+1 ))
+        _msg_error "Packages file '${packages}' does not exist." 0
+    fi
+
+    # Check if the specified bootmodes are supported
+    for bootmode in "${bootmodes[@]}"; do
+        if typeset -f "_make_bootmode_${bootmode}" &> /dev/null; then
+            if typeset -f "_validate_requirements_bootmode_${bootmode}" &> /dev/null; then
+                "_validate_requirements_bootmode_${bootmode}"
+            else
+                _msg_warning "Function '_validate_requirements_bootmode_${bootmode}' does not exist. Validating the requirements of '${bootmode}' boot mode will not be possible."
+            fi
+        else
+            (( validation_error=validation_error+1 ))
+            _msg_error "${bootmode} is not a valid boot mode!" 0
+        fi
+    done
+
+    # Check if the specified airootfs_image_type is supported
+    if typeset -f "_mkairootfs_${airootfs_image_type}" &> /dev/null; then
+        if typeset -f "_validate_requirements_airootfs_image_type_${airootfs_image_type}" &> /dev/null; then
+            "_validate_requirements_airootfs_image_type_${airootfs_image_type}"
+        else
+            _msg_warning "Function '_validate_requirements_airootfs_image_type_${airootfs_image_type}' does not exist. Validating the requirements of '${airootfs_image_type}' airootfs image type will not be possible."
+        fi
+    else
+        (( validation_error=validation_error+1 ))
+        _msg_error "Unsupported image type: '${airootfs_image_type}'" 0
+    fi
+}
+
 _validate_requirements_buildmode_iso() {
-    _validate_requirements_buildmode_all
+    _validate_common_requirements_buildmode_iso_netboot
+    _validate_common_requirements_buildmode_all
     if ! command -v awk &> /dev/null; then
         (( validation_error=validation_error+1 ))
         _msg_error "Validating build mode '${_buildmode}': awk is not available on this host. Install 'awk'!" 0
@@ -779,7 +840,27 @@ _validate_requirements_buildmode_iso() {
 }
 
 _validate_requirements_buildmode_netboot() {
-    _validate_requirements_buildmode_all
+    local _override_cert_list=()
+
+    if [[ "${sign_netboot_artifacts}" == "y" ]]; then
+        # Check if the certificate files exist
+        for _cert in "${cert_list[@]}"; do
+            if [[ -e "${_cert}" ]]; then
+                _override_cert_list+=("$(realpath -- "${_cert}")")
+            else
+                (( validation_error=validation_error+1 ))
+                _msg_error "File '${_cert}' does not exist." 0
+            fi
+        done
+        cert_list=("${_override_cert_list[@]}")
+        # Check if there are at least two certificate files
+        if (( ${#cert_list[@]} < 2 )); then
+            (( validation_error=validation_error+1 ))
+            _msg_error "Two certificates are required for codesigning, but '${cert_list[*]}' is provided." 0
+        fi
+    fi
+    _validate_common_requirements_buildmode_iso_netboot
+    _validate_common_requirements_buildmode_all
     if ! command -v openssl &> /dev/null; then
         (( validation_error=validation_error+1 ))
         _msg_error "Validating build mode '${_buildmode}': openssl is not available on this host. Install 'openssl'!" 0
@@ -968,57 +1049,10 @@ _read_profile() {
 
 # Validate set options
 _validate_options() {
-    local validation_error=0 bootmode _cert _buildmode
-    local pkg_list_from_file=()
-    local bootstrap_pkg_list_from_file=()
-    local _override_cert_list=()
+    local validation_error=0 _buildmode
 
     _msg_info "Validating options..."
-    # Check if the package list file exists and read packages from it
-    if [[ -e "${packages}" ]]; then
-        mapfile -t pkg_list_from_file < <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${packages}")
-        pkg_list+=("${pkg_list_from_file[@]}")
-        if (( ${#pkg_list_from_file[@]} < 1 )); then
-            (( validation_error=validation_error+1 ))
-            _msg_error "No package specified in '${packages}'." 0
-        fi
-    else
-        (( validation_error=validation_error+1 ))
-        _msg_error "Packages file '${packages}' does not exist." 0
-    fi
 
-    # Check if packages for the bootstrap image are specified
-    if [[ "${buildmodes[*]}" == *bootstrap* ]]; then
-        if [[ -e "${bootstrap_packages}" ]]; then
-            mapfile -t bootstrap_pkg_list_from_file < \
-                <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${bootstrap_packages}")
-            bootstrap_pkg_list+=("${bootstrap_pkg_list_from_file[@]}")
-            if (( ${#bootstrap_pkg_list_from_file[@]} < 1 )); then
-                (( validation_error=validation_error+1 ))
-                _msg_error "No package specified in '${bootstrap_packages}'." 0
-            fi
-        else
-            (( validation_error=validation_error+1 ))
-            _msg_error "Bootstrap packages file '${bootstrap_packages}' does not exist." 0
-        fi
-    fi
-    if [[ "${sign_netboot_artifacts}" == "y" ]]; then
-        # Check if the certificate files exist
-        for _cert in "${cert_list[@]}"; do
-            if [[ -e "${_cert}" ]]; then
-                _override_cert_list+=("$(realpath -- "${_cert}")")
-            else
-                (( validation_error=validation_error+1 ))
-                _msg_error "File '${_cert}' does not exist." 0
-            fi
-        done
-        cert_list=("${_override_cert_list[@]}")
-        # Check if there are at least two certificate files
-        if (( ${#cert_list[@]} < 2 )); then
-            (( validation_error=validation_error+1 ))
-            _msg_error "Two certificates are required for codesigning, but '${cert_list[*]}' is provided." 0
-        fi
-    fi
     # Check if pacman configuration file exists
     if [[ ! -e "${pacman_conf}" ]]; then
         (( validation_error=validation_error+1 ))
@@ -1039,31 +1073,6 @@ _validate_options() {
         fi
     done
 
-    # Check if the specified bootmodes are supported
-    for bootmode in "${bootmodes[@]}"; do
-        if typeset -f "_make_bootmode_${bootmode}" &> /dev/null; then
-            if typeset -f "_validate_requirements_bootmode_${bootmode}" &> /dev/null; then
-                "_validate_requirements_bootmode_${bootmode}"
-            else
-                _msg_warning "Function '_validate_requirements_bootmode_${bootmode}' does not exist. Validating the requirements of '${bootmode}' boot mode will not be possible."
-            fi
-        else
-            (( validation_error=validation_error+1 ))
-            _msg_error "${bootmode} is not a valid boot mode!" 0
-        fi
-    done
-    # Check if the specified airootfs_image_type is supported
-    if typeset -f "_mkairootfs_${airootfs_image_type}" &> /dev/null; then
-        if typeset -f "_validate_requirements_airootfs_image_type_${airootfs_image_type}" &> /dev/null; then
-            "_validate_requirements_airootfs_image_type_${airootfs_image_type}"
-        else
-            _msg_warning "Function '_validate_requirements_airootfs_image_type_${airootfs_image_type}' does not exist. Validating the requirements of '${airootfs_image_type}' airootfs image type will not be possible."
-        fi
-    else
-        (( validation_error=validation_error+1 ))
-        _msg_error "Unsupported image type: '${airootfs_image_type}'" 0
-    fi
-
     if (( validation_error )); then
         _msg_error "${validation_error} errors were encountered while validating the profile. Aborting." 1
     fi

From d2315bc98d1e5c07e9d88247d0ad8259677fbac8 Mon Sep 17 00:00:00 2001
From: nl6720 <nl6720@gmail.com>
Date: Tue, 24 Aug 2021 21:16:42 +0300
Subject: [PATCH 3/3] mkarchiso: error out of iso and netboot build modes if no
 boot modes are specified

---
 archiso/mkarchiso | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/archiso/mkarchiso b/archiso/mkarchiso
index fb601c3..6181af2 100755
--- a/archiso/mkarchiso
+++ b/archiso/mkarchiso
@@ -804,6 +804,10 @@ _validate_common_requirements_buildmode_iso_netboot() {
     fi
 
     # Check if the specified bootmodes are supported
+    if (( ${#bootmodes[@]} < 1 )); then
+        (( validation_error=validation_error+1 ))
+        _msg_error "No boot modes specified in '${profile}/profiledef.sh'." 0
+    fi
     for bootmode in "${bootmodes[@]}"; do
         if typeset -f "_make_bootmode_${bootmode}" &> /dev/null; then
             if typeset -f "_validate_requirements_bootmode_${bootmode}" &> /dev/null; then