User tests: Successful: Unsuccessful:
Pull Request followup #48127.
#48127 introduced a new security flag for updates. The limitation was, when a never update has no security issue, it will not flag the update accordingly, see this comment. This pr fixes that. The severity is now shown from the highest update since the currently installed version. See testing instructions for example:
The update site is modified now with the following updates:
Update is shown with security Medium.
Update is shown with security High.
Please select:
Documentation link for guide.joomla.org:
No documentation changes for guide.joomla.org needed
Pull Request link for manual.joomla.org:
No documentation changes for manual.joomla.org needed
| Status | New | ⇒ | Pending |
| Category | ⇒ | Libraries |
| Labels |
Added:
PR-6.2-dev
|
||
| Labels |
Added:
bug
|
||
I have tested this item ✅ successfully on 04e7337
I have tested this item 🔴 unsuccessfully on 04e7337
I have tested this item 🔴 unsuccessfully on 04e7337
I have tested this item 🔴 unsuccessfully on 04e7337
I have tested this item ✅ successfully for the PR's own test instructions, but found two issues
beyond them. This test was first checked by a local AI test suite and then verified manually by me.
Joomla 6.2.0-alpha4-dev, PHP 8.3, MySQL, DDEV. mod_demo 1.0.0 installed, update site
https://digital-peak.com/update.xml, then "Check for updates".
#__updates.security |
Update view | |
|---|---|---|
base 6.2-dev |
2 |
Security release level: Medium |
| with this PR | 3 |
Security release level: High |
Matches the expected result. The severity is correctly taken from 1.0.1 (severity 3) instead of the
latest 1.0.2 (severity 2), and the home dashboard shows "Security update is available for Demo
module!".
findHighestSeverity() returns the last matching severity, not the highest$severity = $update->security;
foreach ($securityUpdates as $securityUpdate) {
if (version_compare(...) && $update->security < $securityUpdate->security) {
$severity = (int) $securityUpdate->security;
}
}The comparison is against $update->security (fixed) instead of the running $severity, so every
candidate that beats the baseline overwrites the previous one. The result is the last qualifying
entry in document order, not the maximum. It happens to give the right answer for the demo XML only
because there is exactly one qualifying entry.
Repro — update XML in the usual newest-first order, installed version 1.0.0:
| version | security |
|---|---|
| 1.0.3 | – (regular release) |
| 1.0.2 | 4 (Critical) |
| 1.0.1 | 2 (Medium) |
Expected: Critical. Observed: #__updates.security = 2 → "Security release level: Medium".
Iteration: null < 4 → 4, then null < 2 → 2 overwrites it. This is exactly the case the PR is
meant to fix (newest update carries no severity), so it silently under-reports a critical update.
Fix:
if (version_compare($securityUpdate->version, $installedVersion, '>') && (int) $severity < (int) $securityUpdate->security) {
$severity = (int) $securityUpdate->security;
}Verified: with that one-line change the table above yields 4 (Critical), and the PR's own demo
scenario still yields 3 (High).
In the else branch ($uid found) the new code calls $extension->load($eid) unguarded:
if (version_compare($current_update->version, $update->version, $operator) == 1) {
$extension->load($eid);
$data = json_decode($extension->manifest_cache, true);
$current_update->security = $this->findHighestSeverity($data['version'], ...);$eid can be falsy here — the line 6 lines above (if ((int) $update->extension_id === 0 && $eid))
explicitly anticipates that. Table::load(null) returns early without loading, manifest_cache
stays null, $data becomes null, and $data['version'] is null → TypeError on the
non-nullable string $installedVersion. The whole update check aborts, so no updates are shown.
Repro (6.2-dev + this PR):
mod_ghost, A with version 1.0.0, B with version 2.0.0$update->find() matches on element/type/client_id/folder, not on update_site_id, so B findsphp cli/joomla.php update:extensions:check).Observed:
Deprecated: json_decode(): Passing null to parameter #1 ($json) of type string is deprecated in .../Updater.php on line 411
Warning: Trying to access array offset on null in .../Updater.php on line 412
Joomla\CMS\Updater\Updater::findHighestSeverity(): Argument #1 ($installedVersion) must be of type string, null given
The same shape is reachable via the public getAvailableUpdates(), which does not purge
#__updates beforehand.
Fix — guard it like the other branch, e.g.:
if (version_compare($current_update->version, $update->version, $operator) == 1) {
if ($eid) {
$extension->load($eid);
$data = json_decode($extension->manifest_cache, true);
if (!empty($data['version'])) {
$current_update->security = $this->findHighestSeverity($data['version'], $current_update, $update_result['security'] ?? []);
}
}
$retVal[] = $current_update;
}protected array $security = []; in ExtensionAdapter has no docblock (@var / @since), unlike
the rest of the new code which correctly carries @since __DEPLOY_VERSION__.
I fixed the AI findings, @dautrich and @tecpromotion can you test again?
I fixed the AI findings, @dautrich and @tecpromotion can you test again? I added a new update with version 1.0.3 which has no security issue.
I fixed the AI findings, @dautrich and @tecpromotion can you test again? I added a new update with version 1.0.3 which has no security issue to have the AI finding also covered.
I have tested this item ✅ successfully on 4b49b80
I have tested this item ✅ successfully on 4b49b80
Each one is listed then. If we want to change that, then we need to create another pr as this one tackles another issue.
does it break the button?
Isnt it enough to just say "security update available"
I can do another pr for that. Please mark your test as successful as this pr solves a different issue.
I have tested this item ✅ successfully on 969cb6d
I have tested this item ✅ successfully on 969cb6d
Confirming that it correctly shows the highest severity
Still needs more work for the quickicon - either here or in another PR
I've restored @dautrich 's test result in the issue tracker as the commit which has invalidated the test was just a clean branch update.
@laoneo Please when you do branch updates, restore any human test results after that by using the "Alter test" in the issue tracker. I don't remember now how often I have told maintainers to do so in order to not cause additional work for other maintainers. Thanks in advance.
| Status | Pending | ⇒ | Ready to Commit |
RTC
RTC
@richard67 I wanted to wait for the second test.
| Status | Ready to Commit | ⇒ | Fixed in Code Base |
| Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2026-08-11 09:09:06 |
| Closed_By | ⇒ | MacJoom | |
| Labels |
Added:
RTC
|
||
Thank you!
I have tested this item ✅ successfully on 04e7337
This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/48190.