RTC bug PR-6.2-dev Pending

User tests: Successful: Unsuccessful:

avatar laoneo
laoneo
4 Aug 2026

Pull Request followup #48127.

  • I read the Generative AI policy and my contribution is either not created with the help of AI or is compatible with the policy and GNU/GPL 2 or later.

Summary of Changes

#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:

Testing Instructions

The update site is modified now with the following updates:

  • Version 0.9.0 -> severity 4 (Critical)
  • Version 1.0.0 -> severity null (no information)
  • Version 1.0.1 -> severity 3 (High)
  • Version 1.0.2 -> severity 2 (Medium)
  • Version 1.0.3 -> severity null (no information)
    The file to download has version 1.0.0 with no severity.

  • Install the module mod_demo.zip
  • Open the page /administrator/index.php?option=com_installer&view=update
  • Click on "Check for updates"

Actual result BEFORE applying this Pull Request

Update is shown with security Medium.

Expected result AFTER applying this Pull Request

Update is shown with security High.

Link to documentations

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

avatar laoneo laoneo - open - 4 Aug 2026
avatar laoneo laoneo - change - 4 Aug 2026
Status New ⇒ Pending
avatar joomla-cms-bot joomla-cms-bot - change - 4 Aug 2026
Category ⇒ Libraries
avatar laoneo laoneo - change - 4 Aug 2026
The description was changed
avatar laoneo laoneo - edited - 4 Aug 2026
avatar laoneo laoneo - change - 4 Aug 2026
Labels Added: PR-6.2-dev
avatar laoneo laoneo - change - 4 Aug 2026
The description was changed
avatar laoneo laoneo - edited - 4 Aug 2026
avatar laoneo laoneo - change - 4 Aug 2026
The description was changed
avatar laoneo laoneo - edited - 4 Aug 2026
avatar laoneo laoneo - change - 4 Aug 2026
Labels Added: bug
02fa9e4 4 Aug 2026 avatar laoneo doc
44d9d92 5 Aug 2026 avatar laoneo doc
avatar dautrich dautrich - test_item - 7 Aug 2026 - Tested successfully
avatar dautrich
dautrich - comment - 7 Aug 2026

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.

avatar dautrich
dautrich - comment - 7 Aug 2026

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.

avatar tecpromotion tecpromotion - test_item - 7 Aug 2026 - Tested unsuccessfully
avatar tecpromotion
tecpromotion - comment - 7 Aug 2026

I have tested this item 🔴 unsuccessfully on 04e7337


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/48190.

avatar tecpromotion
tecpromotion - comment - 7 Aug 2026

I have tested this item 🔴 unsuccessfully on 04e7337


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/48190.

avatar tecpromotion
tecpromotion - comment - 7 Aug 2026

I have tested this item 🔴 unsuccessfully on 04e7337


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/48190.

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.

Verification (PR test instructions)

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!".

Finding 1 — 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).

Finding 2 — fatal error when the update record belongs to a not-installed extension

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):

  1. Create two enabled extension update sites A and B that both offer the same not installed
    extension 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 finds
    A's freshly written row).
  2. Run "Check for updates" (or php 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;
}

Nitpick

protected array $security = []; in ExtensionAdapter has no docblock (@var / @since), unlike
the rest of the new code which correctly carries @since __DEPLOY_VERSION__.

4b49b80 10 Aug 2026 avatar laoneo doc
avatar laoneo
laoneo - comment - 10 Aug 2026

I fixed the AI findings, @dautrich and @tecpromotion can you test again?

avatar laoneo
laoneo - comment - 10 Aug 2026

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.

avatar laoneo
laoneo - comment - 10 Aug 2026

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.

avatar laoneo laoneo - change - 10 Aug 2026
The description was changed
avatar laoneo laoneo - edited - 10 Aug 2026
avatar dautrich dautrich - test_item - 10 Aug 2026 - Tested successfully
avatar dautrich
dautrich - comment - 10 Aug 2026

I have tested this item ✅ successfully on 4b49b80


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/48190.

avatar dautrich
dautrich - comment - 10 Aug 2026

I have tested this item ✅ successfully on 4b49b80


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/48190.

avatar brianteeman
brianteeman - comment - 11 Aug 2026

It works as described BUT what happens if there are multiple extensions with security updates

image
avatar laoneo
laoneo - comment - 11 Aug 2026

Each one is listed then. If we want to change that, then we need to create another pr as this one tackles another issue.

avatar brianteeman
brianteeman - comment - 11 Aug 2026

does it break the button?
Isnt it enough to just say "security update available"

avatar laoneo
laoneo - comment - 11 Aug 2026

I can do another pr for that. Please mark your test as successful as this pr solves a different issue.

avatar brianteeman brianteeman - test_item - 11 Aug 2026 - Tested successfully
avatar brianteeman
brianteeman - comment - 11 Aug 2026

I have tested this item ✅ successfully on 969cb6d


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/48190.

avatar brianteeman
brianteeman - comment - 11 Aug 2026

I have tested this item ✅ successfully on 969cb6d


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/48190.

avatar brianteeman
brianteeman - comment - 11 Aug 2026

Confirming that it correctly shows the highest severity

Still needs more work for the quickicon - either here or in another PR

avatar richard67 richard67 - alter_testresult - 11 Aug 2026 - dautrich: Tested successfully
avatar richard67
richard67 - comment - 11 Aug 2026

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.

avatar richard67 richard67 - change - 11 Aug 2026
Status Pending ⇒ Ready to Commit
avatar richard67
richard67 - comment - 11 Aug 2026

RTC


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/48190.

avatar richard67
richard67 - comment - 11 Aug 2026

RTC


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/48190.

avatar laoneo
laoneo - comment - 11 Aug 2026

@richard67 I wanted to wait for the second test.

avatar MacJoom MacJoom - change - 11 Aug 2026
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
avatar MacJoom MacJoom - close - 11 Aug 2026
avatar MacJoom MacJoom - merge - 11 Aug 2026
avatar MacJoom
MacJoom - comment - 11 Aug 2026

Thank you!

Add a Comment

Login with GitHub to post a comment