diff --git a/core/modules/update/tests/modules/aaa_update_test/aaa_update_test.info.yml b/core/modules/update/tests/modules/aaa_update_test/aaa_update_test.info.yml index 19367eac8cd..ee90601b12d 100644 --- a/core/modules/update/tests/modules/aaa_update_test/aaa_update_test.info.yml +++ b/core/modules/update/tests/modules/aaa_update_test/aaa_update_test.info.yml @@ -2,4 +2,3 @@ name: 'AAA Update test' type: module description: 'Support module for update module testing.' package: Testing -version: VERSION diff --git a/core/modules/update/tests/src/Functional/UpdateContribTest.php b/core/modules/update/tests/src/Functional/UpdateContribTest.php index 7c50fafd89c..0fff1678960 100644 --- a/core/modules/update/tests/src/Functional/UpdateContribTest.php +++ b/core/modules/update/tests/src/Functional/UpdateContribTest.php @@ -794,6 +794,43 @@ class UpdateContribTest extends UpdateTestBase { $this->confirmUnsupportedStatus('8.x-1.1', '8.x-2.0', 'Recommended version:'); } + /** + * Tests messages for invalid, empty and missing version strings. + */ + public function testNonStandardVersionStrings() { + $version_infos = [ + 'invalid' => [ + 'version' => 'llama', + 'expected' => 'Invalid version: llama', + ], + 'empty' => [ + 'version' => '', + 'expected' => 'Empty version', + ], + 'null' => [ + 'expected' => 'Invalid version: Unknown', + ], + ]; + foreach ($version_infos as $version_info) { + $system_info = [ + 'aaa_update_test' => [ + 'project' => 'aaa_update_test', + 'hidden' => FALSE, + ], + ]; + if (isset($version_info['version'])) { + $system_info['aaa_update_test']['version'] = $version_info['version']; + } + $this->config('update_test.settings')->set('system_info', $system_info)->save(); + $this->refreshUpdateStatus([ + 'drupal' => '0.0', + $this->updateProject => '1_0-supported', + ]); + $this->standardTests(); + $this->assertSession()->elementTextContains('css', $this->updateTableLocator, $version_info['expected']); + } + } + /** * Asserts that a core compatibility message is correct for an update. * diff --git a/core/modules/update/update.compare.inc b/core/modules/update/update.compare.inc index d318e6c4863..1eadbed71f3 100644 --- a/core/modules/update/update.compare.inc +++ b/core/modules/update/update.compare.inc @@ -196,6 +196,9 @@ function update_calculate_project_data($available) { * version (e.g., 5.x-1.5-beta1, 5.x-1.5-beta2, and 5.x-1.5). Development * snapshots for a given major version are always listed last. * + * NOTE: This function *must* set a value for $project_data['status'] before + * returning, or the rest of the Update Manager will break in unexpected ways. + * * @param $project_data * An array containing information about a specific project. * @param $available @@ -263,11 +266,19 @@ function update_calculate_project_update_status(&$project_data, $available) { } // Figure out the target major version. + // Off Drupal.org, '0' could be a valid version string, so don't use empty(). + if (!isset($project_data['existing_version']) || $project_data['existing_version'] === '') { + $project_data['status'] = UpdateFetcherInterface::UNKNOWN; + $project_data['reason'] = t('Empty version'); + return; + } try { $existing_major = ModuleVersion::createFromVersionString($project_data['existing_version'])->getMajorVersion(); } catch (UnexpectedValueException $exception) { // If the version has an unexpected value we can't determine updates. + $project_data['status'] = UpdateFetcherInterface::UNKNOWN; + $project_data['reason'] = t('Invalid version: @existing_version', ['@existing_version' => $project_data['existing_version']]); return; } $supported_branches = [];