Problem/Motivation
in #2990511-39: Add comprehensive test coverage for update status for security releases cases were found where in Update reports, if security release is needed for current minor and is also available for minor the previous minor security update is listed also.
An example:
The current core version is 8.1.0 which insecure
- 8.1.2 is a security update, not insecure
- 8.0.2 is a security update, not insecure
- 8.0.2, in addition to 8.1.2, is shown as security update even though it would be downgrade

This seems separate issue than #2865920: Add tests for when a single supported branch has 2 security updates that are both not insecure
Proposed resolution
Downgrades should never be shown as a Security update.
The current fix for #2804155: If the next minor version of core has a security release, status still says "Security update required!" even if the site is on an equivalent, secure release already does not fix this issue.
Remaining tasks
Figure out the fix
patch
review
User interface changes
None
API changes
None
Data model changes
None
| Comment | File | Size | Author |
|---|---|---|---|
| #22 | 2992631-22-after.png | 286.69 KB | jungle |
| #22 | 2992631-22-before.png | 298.53 KB | jungle |
| #20 | 2992631.18_20.interdiff.txt | 588 bytes | dww |
| #20 | 2992631-20.patch | 4.86 KB | dww |
| #14 | 2992631-14.test-only.patch | 3.7 KB | dww |
Comments
Comment #2
xjmWell, I would say "Downgrades within the same major release should never be shown as security updates." There are times that an older security release really could be the only supported option, if newer releases have been marked insecure/revoked/etc. without newer security releases being created. This also applies to the case where the site is on 8.x-3.0-beta2 of a module and the most recent security release is 8.x-2.2. In that scenario, 2.2 really is the most recommended version for a stable site.
Comment #3
xjmComment #4
cilefen commentedComment #6
xjmThis is at least major and possibly critical because of its relationship to #2990476: If the site is on an insecure version of an old minor and there is a secure version of that old minor available, the update status report should link that release. Bumping to critical for now.
Comment #7
tedbowHere is patch to start
There were some todos in our tests that point to #2865920: Add tests for when a single supported branch has 2 security updates that are both not insecure but actually are the problem that is being described here. I removed those todos and added the test cases.
re #3 I left one of the todos in that points to this problem
I am not sure if we should also solve that here.
Comment #9
dwwI think I just ran into another example of this in the real world.
I'm trying to test #3114707: Add color to summary element to improve UX of core compatibility info on available updates report and I searched for a contrib that's got a requirement on 8.8.x core and a security update required. I found VBO (side note, see #3116581: Use core_version_requirement, not a version dependency on drupal:views).
Right now with a clean 8.9.x install of core, if you install VBO 8.x-3.3, your available update report will look like this:
This is the same bug, right?
I re-rolled #7 (no longer applies), and now my available updates report for VBO looks as expected:
Not entirely clear what else is needed here. I'll more closely review when I can and see if there's any reason not to RTBC this.
Thanks,
-Derek
p.s. Interdiff is all kinds of confused by the re-roll, so here's a raw diff of the two patch files.
p.p.s. EDIT: changed the embedded screenshots to use the ones from comment #10.
Comment #10
dwwSorry for the noise, but my test site was a bit screwy when I took those screenshots. Needed to clear caches to get the Download links. ;) These are the accurate screenshots.
Comment #11
dwwInitial review:
Comment grammar doesn't parse. Should be:
// If the site is on an alpha/beta/RC of an upcoming minor and there is
// an RC version with a security update, it should be recommended.
I botched the spacing on the reroll. I think Component should go first, without a newline between it and the others...
We shouldn't use str_replace() for this, or we screw up things like 8.x-8.x-dev releases. We should be more careful and do a preg_replace() anchored to the start of the string. Or something...
Bigger picture... I'm confused why we have this bug at all. Once upon a time, update_calculate_project_update_status() would stop searching the release history as soon as it found your currently installed release. So I'm not sure how it gets to this state where it's finding security releases that are older than your installed release. I'd have to dig a lot deeper to figure out why that changed. But it makes me nervous that there might be other bugs lurking if update_calculate_project_update_status() keeps processing releases that are older than what you've got...
Yeah, weird, it's still there:
So, yeah, needs further investigation to understand why this patch is needed at all. ;)
p.s. #3085662: Remove Drupal::CORE_COMPATIBILITY because it is not accurate when modules can be compatible with multiple core branches -- sad to keep adding usages of
\Drupal::CORE_COMPATIBILITYComment #12
swatichouhan012 commentedI have updated patch wrt #11, point 1 and point 2.
Comment #13
dwwI'm looking into the "bigger picture" from #10. Stay tuned...
Comment #14
dwwOk, here's the deal...
B/c of this:
if your currently-installed version is one of those conditions (e.g. insecure), then we never hit this code block later:
So this function loops over every possible release. :( In most cases, we skip things that are older, but not for security updates. That's what the fix in #7 is addressing -- special-case the security release stuff to ignore older releases.
IMHO, the better solution is to not skip the current version, even if insecure, so that we properly bail out of this function when we mean to.
I first tried adding the
break;at the end of the initial code block that notices if we're on the current release:However, if we break that soon, then we never set
recommendorlatest_version, and if you've got a module that's up-to-date (current should be recommended) eventually we hit this:So that's no good, either...
Therefore, I think the smallest, safest fix for this bug (which also prevents us from needlessly looping over a ton of releases we don't care about) is the attached patch. We only do the "otherwise, ignore stuff..." code block in an
elseof testing if we're looking at the current release.Identical test changes from #7. In fact, attaching those as a test-only patch so we see the failures from the new test coverage here. Fails locally. With the full patch, all update tests are passing locally. I hope the bot agrees.
Interdiff is pretty meaningless, since it's an entirely different approach to the changes for update.compare.inc.
p.s. @swatichouhan012 re: #12: thanks for helping. Unfortunately you didn't fix #11.2 as intended. Thankfully, it doesn't matter since this new approach doesn't need any new
usestatements at all. ;)p.p.s. Adding #3100110: Convert update_calculate_project_update_status() into a class as related. I'll be the first to admit that this function is way too long and complicated for anyone other than the original author (me) to really understand all the subtleties and nuances for the kind of analysis / fix I just did. :( Yes, we should re-factor / re-organize it into a class and make it easier for other people to make sense of.
Comment #16
dwwSelf-review:
This can be
elseif(), then we don't have to indent it all. Although we'd still have to change the indentation of all the conditions forifvs.elseif. :/ So it'd only save the indentation of thecontinueand would eliminate the need for the extra}. ;)Wish we had a better standard for multi-line complex conditionals like this. Sadly #1539712: [policy, no patch] Coding standards for breaking function calls and language constructs across lines wouldn't help and we'd still need to indent the conditions differently to account for
ifvs.elseif. /shrugMeanwhile, I believe this is back-portable to 8.8.x, so moving the version selector accordingly. Patch still applies cleanly to 8.8.x and 9.0.x, too.
Comment #18
dww#17 was just a random fail, but I realized I uploaded the wrong version of the formatting I was aiming for, anyway.
Comment #19
tedbowI am comparing the patched version with the version in 8.9.x. I think now that this is a
esleifforif ($project_data['existing_version'] === $version) {and not it's own if block, we should change this comment indicate this will only happen for versions other than the current.
If the if block above was smaller and didn't also contain it's own if,elseif,elseif block we might not need this but looking at it is confusing what the new elseif corresponds
maybe something like: "If $release is not the existing release and is unpublished, insecure or unsupported, ignore it."
Otherwise I think it looks good
Comment #20
dwwRe: #19: 👍
How's this?
See also my latest thoughts at #3100110-21: Convert update_calculate_project_update_status() into a class
Comment #21
dww9.1.x was random fail in Drupal\Tests\quickedit\FunctionalJavascript\QuickEditIntegrationTest -- requeued.
Comment #22
jungleManually tested the patch in #18 against 8.9.x#225d565b9060b0f7357d5fd3232d90fd5d7e766b
The patch works as expected, RTBC +1.
Comment #23
jungleMeanwhile, I am thinking of the following
Recommended version:toRecommended version by maintainer. To me, if I am using a branch, recommended version from the same branch would make more sense. Take the screenshot in #22 as an example, I was using Drupal core 8.9.x-dev, why recommended me 8.8.4. I'd like 8.9.0-beta1 being recommended rather than 8.8.4.To distinguish the recommended version by the maintainer and by the update system is unnecessary. But we could make it more clear that it's by the maintainer.
which > current version? Take the VBO module in #22 as example, the current version is 3.3.0 and the latest version is 3.6.0. My point is that version 3.4.0, 3.5.0 and 3.6.0 should be listed too. With all available releases listed, it may push/encourage people to do the update. It looks like saying that, hey, site owner, you are too far away from the latest version.I think we should introduce a filter or setting which similar to the
Email notification thresholdUnder theUpdate Manager settingsTo allow end-users care about Stable releases only, or RC/beta/alpha/dev releases are ok. The use case is that some people only care about the stable releases, some people may care of RC, beta, even alpha releases. We should provide such an option.
Of course, all the above can be done in separate issues if they will be proceeding
Comment #24
tedbow@jungle thanks for the review.
Recommended version by maintaineris actually not accurate the current XML doesn't have this information and it was never used in exactly this way.There is check box for recommended branch on the project page for maintainers but that is what is recommended on the project page not what the update module recommends, which currently that latest in a version in the major. See #3100115: The update module should recommend updates based on supported_branches rather than major versions majors
whoops didn't see this. Yes these would all have to be separate issues.
Comment #25
clayfreemanLGTM; tests seem to be passing and I can't find anything wrong with the proposed changes.
Comment #26
tedbow+1 for the RTBC. Thanks @dww
Comment #27
alexpottCommitted e1b9321 and pushed to 9.1.x. Thanks!
I'm going ping the release managers about backport.
This looks okay to me. Hard t review but it makes sense once I groked what
was doing.
The code is definitely over-complex and hard to review / test. So it's great that our coverage is improving.
Comment #29
dwwSweet, thanks! FYI: #20 applies cleanly all the way back to 8.8.x branch, so this should be cherry-pickable and doesn't require any new patches.
Cheers,
-Derek
Comment #33
alexpottDiscussed with @catch and we agreed to backport this all the way back to 8.8.x
Comment #34
dwwSweet, thanks!