From c0cf3b84dc35370728069316b57a9fd69b439ff6 Mon Sep 17 00:00:00 2001
From: tedbow <tedbow@240860.no-reply.drupal.org>
Date: Mon, 5 Dec 2022 02:45:30 +0000
Subject: [PATCH] Issue #3320558 by bnjmnm, tedbow: When parsing releases,
 place ProjectRelease::createFromArray in a try block

---
 package_manager/src/ProjectInfo.php           | 13 ++++++++-
 .../aaa_automatic_updates_test.7.0.1.xml      | 28 +++++++++++++++++++
 .../tests/src/Kernel/ProjectInfoTest.php      | 12 +++++++-
 3 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/package_manager/src/ProjectInfo.php b/package_manager/src/ProjectInfo.php
index 86ea96ef12..f47a1013e5 100644
--- a/package_manager/src/ProjectInfo.php
+++ b/package_manager/src/ProjectInfo.php
@@ -8,6 +8,7 @@ use Composer\Semver\Comparator;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\update\ProjectRelease;
 use Drupal\Core\Extension\ExtensionVersion;
+use Drupal\Core\Utility\Error;
 use Drupal\update\UpdateManagerInterface;
 
 /**
@@ -120,7 +121,17 @@ final class ProjectInfo {
     $support_branches = explode(',', $available_updates['supported_branches']);
     $installable_releases = [];
     foreach ($available_updates['releases'] as $release_info) {
-      $release = ProjectRelease::createFromArray($release_info);
+      try {
+        $release = ProjectRelease::createFromArray($release_info);
+      }
+      catch (\UnexpectedValueException $exception) {
+        // Ignore releases that are in an invalid format. Although this is
+        // unlikely we should still only process releases in the correct format.
+        \Drupal::logger('package_manager')
+          ->error(sprintf('Invalid project format: %s', print_r($release_info, TRUE)), Error::decodeException($exception));
+        continue;
+      }
+
       $version = $release->getVersion();
       if ($installed_version) {
         $semantic_version = LegacyVersionUtility::convertToSemanticVersion($version);
diff --git a/package_manager/tests/fixtures/release-history/aaa_automatic_updates_test.7.0.1.xml b/package_manager/tests/fixtures/release-history/aaa_automatic_updates_test.7.0.1.xml
index 82e49f50f7..678adce6f8 100644
--- a/package_manager/tests/fixtures/release-history/aaa_automatic_updates_test.7.0.1.xml
+++ b/package_manager/tests/fixtures/release-history/aaa_automatic_updates_test.7.0.1.xml
@@ -14,6 +14,7 @@ Contains metadata about the following (fake) releases of aaa_automatic_updates_t
 - 8.x-6.0-alpha1
 - 7.0.x-dev
 - 8.x-6.x-dev
+- 8.x-5.x - An invalid release to ensure invalid releases do not affect processing other releases.
 -->
 <project xmlns:dc="http://purl.org/dc/elements/1.1/">
 <title>AAA</title>
@@ -134,5 +135,32 @@ Contains metadata about the following (fake) releases of aaa_automatic_updates_t
             <term><name>Release type</name><value>Bug fixes</value></term>
         </terms>
     </release>
+    <release>
+        <name>AAA 8.x-5.x</name>
+        <version>8.x-5.x</version>
+        <status>published</status>
+        <release_link>http://example.com/aaa_automatic_updates_test-9-5-0-dev-release</release_link>
+        <download_link/>
+        <date/>
+        <filesize/>
+        <files>
+            <file>
+                <url/>
+                <archive_type/>
+                <md5/>
+                <size/>
+            </file>
+            <file>
+                <url/>
+                <archive_type/>
+                <md5/>
+                <size/>
+            </file>
+        </files>
+        <terms>
+            <term><name>Release type</name><value>New features</value></term>
+            <term><name>Release type</name><value>Bug fixes</value></term>
+        </terms>
+    </release>
 </releases>
 </project>
diff --git a/package_manager/tests/src/Kernel/ProjectInfoTest.php b/package_manager/tests/src/Kernel/ProjectInfoTest.php
index b9924557a1..8bb079875e 100644
--- a/package_manager/tests/src/Kernel/ProjectInfoTest.php
+++ b/package_manager/tests/src/Kernel/ProjectInfoTest.php
@@ -2,7 +2,9 @@
 
 namespace Drupal\Tests\package_manager\Kernel;
 
+use Drupal\Core\Logger\RfcLogLevel;
 use Drupal\package_manager\ProjectInfo;
+use ColinODell\PsrTestLogger\TestLogger;
 
 /**
  * @coversDefaultClass \Drupal\package_manager\ProjectInfo
@@ -126,6 +128,10 @@ class ProjectInfoTest extends PackageManagerKernelTestBase {
    * Tests a project that is not in the codebase.
    */
   public function testNewProject(): void {
+    $logger = new TestLogger();
+    $this->container->get('logger.factory')
+      ->get('package_manager')
+      ->addLogger($logger);
     $fixtures_directory = __DIR__ . '/../../fixtures/release-history/';
     $metadata_fixtures['drupal'] = $fixtures_directory . 'drupal.9.8.2.xml';
     $metadata_fixtures['aaa_automatic_updates_test'] = $fixtures_directory . 'aaa_automatic_updates_test.7.0.1.xml';
@@ -151,8 +157,9 @@ class ProjectInfoTest extends PackageManagerKernelTestBase {
       '8.x-6.0-alpha1',
       '7.0.x-dev',
       '8.x-6.x-dev',
+      '8.x-5.x',
     ];
-    $uninstallable_releases = ['7.0.x-dev', '8.x-6.x-dev'];
+    $uninstallable_releases = ['7.0.x-dev', '8.x-6.x-dev', '8.x-5.x'];
     $installable_releases = array_values(array_diff($all_releases, $uninstallable_releases));
     $this->assertSame(
       $all_releases,
@@ -166,6 +173,9 @@ class ProjectInfoTest extends PackageManagerKernelTestBase {
     // Ensure we have not changed the state the update module uses to store
     // the last checked time.
     $this->assertSame(123, $state->get('update.last_check'));
+
+    $this->assertTrue($logger->hasRecordThatContains('Invalid project format: Array', RfcLogLevel::ERROR));
+    $this->assertTrue($logger->hasRecordThatContains('[name] => AAA 8.x-5.x', RfcLogLevel::ERROR));
   }
 
   /**
-- 
GitLab