From dc7269d46a367002e82e53382dcc59e8d2ffbf74 Mon Sep 17 00:00:00 2001
From: Tim van Dijen <tvdijen@gmail.com>
Date: Sat, 5 Feb 2022 21:25:49 +0100
Subject: [PATCH] Refactor getArrayize/getOptionalArrayize

---
 lib/SimpleSAML/Configuration.php        | 35 +++++++++++++++++++------
 lib/SimpleSAML/Metadata/SAMLBuilder.php |  8 +++---
 modules/saml/lib/IdP/SAML2.php          | 10 ++++---
 3 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/lib/SimpleSAML/Configuration.php b/lib/SimpleSAML/Configuration.php
index 60513d29c..cdb75671d 100644
--- a/lib/SimpleSAML/Configuration.php
+++ b/lib/SimpleSAML/Configuration.php
@@ -876,21 +876,40 @@ class Configuration implements Utils\ClearableState
      * If the configuration option isn't an array, it will be converted to an array.
      *
      * @param string $name The name of the option.
-     * @param mixed  $default A default value which will be returned if the option isn't found. The option will be
-     *                       required if this parameter isn't given. The default value can be any value, including
-     *                       null.
      *
-     * @return mixed The option with the given name, or $default if the option isn't found and $default is specified.
+     * @return mixed The option with the given name.
      */
-    public function getArrayize(string $name, $default = self::REQUIRED_OPTION)
+    public function getArrayize(string $name): array
     {
-        $ret = $this->getValue($name, $default);
+        $ret = $this->getValue($name);
 
-        if ($ret === $default) {
+        if (!is_array($ret)) {
+            $ret = [$ret];
+        }
+
+        return $ret;
+    }
+
+
+    /**
+     * This function retrieves an array configuration option.
+     *
+     * If the configuration option isn't an array, it will be converted to an array.
+     *
+     * @param string $name The name of the option.
+     * @param mixed  $default A default value which will be returned if the option isn't found.
+     *                       The default value can be null or an array.
+     *
+     * @return mixed The option with the given name, or $default if the option isn't found and $default is specified.
+     */
+    public function getOptionalArrayize(string $name, $default): ?array
+    {
+        if (!$this->hasValue($name)) {
             // the option wasn't found, or it matches the default value. In any case, return this value
-            return $ret;
+            return $default;
         }
 
+        $ret = $this->getValue($name);
         if (!is_array($ret)) {
             $ret = [$ret];
         }
diff --git a/lib/SimpleSAML/Metadata/SAMLBuilder.php b/lib/SimpleSAML/Metadata/SAMLBuilder.php
index 7e4933078..d37f65e9f 100644
--- a/lib/SimpleSAML/Metadata/SAMLBuilder.php
+++ b/lib/SimpleSAML/Metadata/SAMLBuilder.php
@@ -518,10 +518,10 @@ class SAMLBuilder
 
         $e->setSingleLogoutService(self::createEndpoints($metadata->getEndpoints('SingleLogoutService'), false));
 
-        $e->setNameIDFormat($metadata->getArrayizeString('NameIDFormat', []));
+        $e->setNameIDFormat($metadata->getOptionalArrayizeString('NameIDFormat', []));
 
         $endpoints = $metadata->getEndpoints('AssertionConsumerService');
-        foreach ($metadata->getArrayizeString('AssertionConsumerService.artifact', []) as $acs) {
+        foreach ($metadata->getOptionalArrayizeString('AssertionConsumerService.artifact', []) as $acs) {
             $endpoints[] = [
                 'Binding'  => Constants::BINDING_HTTP_ARTIFACT,
                 'Location' => $acs,
@@ -575,7 +575,7 @@ class SAMLBuilder
 
         $e->setSingleLogoutService(self::createEndpoints($metadata->getEndpoints('SingleLogoutService'), false));
 
-        $e->setNameIDFormat($metadata->getArrayizeString('NameIDFormat', []));
+        $e->setNameIDFormat($metadata->getOptionalArrayizeString('NameIDFormat', []));
 
         $e->setSingleSignOnService(self::createEndpoints($metadata->getEndpoints('SingleSignOnService'), false));
 
@@ -614,7 +614,7 @@ class SAMLBuilder
             false
         ));
 
-        $e->setNameIDFormat($metadata->getArrayizeString('NameIDFormat', []));
+        $e->setNameIDFormat($metadata->getOptionalArrayizeString('NameIDFormat', []));
 
         $this->entityDescriptor->addRoleDescriptor($e);
     }
diff --git a/modules/saml/lib/IdP/SAML2.php b/modules/saml/lib/IdP/SAML2.php
index c068e524e..620d7893b 100644
--- a/modules/saml/lib/IdP/SAML2.php
+++ b/modules/saml/lib/IdP/SAML2.php
@@ -456,7 +456,7 @@ class SAML2
             throw new Exception('Unable to use any of the ACS endpoints found for SP \'' . $spEntityId . '\'');
         }
 
-        $IDPList = array_unique(array_merge($IDPList, $spMetadata->getArrayizeString('IDPList', [])));
+        $IDPList = array_unique(array_merge($IDPList, $spMetadata->getOptionalArrayizeString('IDPList', [])));
         if ($ProxyCount === null) {
             $ProxyCount = $spMetadata->getOptionalInteger('ProxyCount', null);
         }
@@ -796,7 +796,7 @@ class SAML2
             'entityid' => $entityid,
             'SingleSignOnService' => $sso,
             'SingleLogoutService' => $slo,
-            'NameIDFormat' => $config->getArrayizeString('NameIDFormat', [Constants::NAMEID_TRANSIENT]),
+            'NameIDFormat' => $config->getOptionalArrayizeString('NameIDFormat', [Constants::NAMEID_TRANSIENT]),
         ];
 
         $cryptoUtils = new Utils\Crypto();
@@ -1254,9 +1254,11 @@ class SAML2
 
         if ($nameIdFormat === null || !isset($state['saml:NameID'][$nameIdFormat])) {
             // either not set in request, or not set to a format we supply. Fall back to old generation method
-            $nameIdFormat = current($spMetadata->getArrayizeString('NameIDFormat', []));
+            $nameIdFormat = current($spMetadata->getOptionalArrayizeString('NameIDFormat', []));
             if ($nameIdFormat === false) {
-                $nameIdFormat = current($idpMetadata->getArrayizeString('NameIDFormat', [Constants::NAMEID_TRANSIENT]));
+                $nameIdFormat = current(
+                    $idpMetadata->getOptionalArrayizeString('NameIDFormat', [Constants::NAMEID_TRANSIENT])
+                );
             }
         }
 
-- 
GitLab