Problem/Motivation
NULL results are being passed to array_filter function.
Issue 3348686 allows for modules to provide translations for specific links using an implementation of moduleHandler->alter here. The problem is that this occurs after checking for empty results. Certain implementations of the moduleHandler->alter may empty this results array (see issue 3358576 for language_switcher_extended module). This can result in an empty result array being passed to the array_filter function causing error.
if (!empty($result)) {
// Allow modules to provide translations for specific links.
$this->moduleHandler->alter('language_switch_links', $result, $type, $url);
$result = array_filter($result, function (array $link): bool {}
Although this issue is caused by the calling of moduleHandler->alter and works assuming all defaults, it should safely handle cases where a NULL value is passed as result by other core or contrib alterations.
Steps to reproduce
- Steps to reproduce
- Install all of the core Multilingual modules
- Add another language
- Enable a content type for content translation (including its published field)
- Use URL -> Path for the language detection
- Place the Language switcher content block
- configure a 3rd party module (for example, language switcher extended) to hide block when no translation is expected.
- Select
Alter the language switcher for untranslated content entities - Select
Hide the language switcher linkfor the untranslated handler - Navigate to a page with no translations
Proposed resolution
Add an additional !empty() check after all modules have made alterations to the link list.
API changes
The API is not changed but now documented in language.api.php now and a CR #3512283 is drafted.
| Comment | File | Size | Author |
|---|---|---|---|
| #59 | 3362713-check-empty-language-switch-link-results-59.patch | 4.39 KB | znak |
| #56 | drupal-language-switch-links-guard-check.patch | 2.09 KB | yi_jiang |
Issue fork drupal-3362713
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
thhafner commentedComment #3
thhafner commentedComment #4
smustgrave commentedAs a bug it will need a test case to show the issue.
Triggering 11.x also.
Comment #5
lordzik commentedWhen is this patch going to be commited? This bug is crashing websites updated from Drupal 9.5.7 to 9.5.10!
Priority should be higher than Normal...
Comment #6
lordzik commentedI'm changing priority to critical as this bug makes WSOD also in D10.1.6!
I'm not changing status to revieved and tested as i'm not a developer although this patch fixed WSOD.
Comment #7
lordzik commentedComment #8
yospyn commentedConfirming #2 worked for me on Core 10.2.3. The switcher was working fine on translation-enabled content that has a translation, but not on translation-enabled content that does NOT have a translation.
The problem also only appeared if you were logged out, not if you were logged in (at least as an admin).
Comment #10
devkinetic commentedI ran into this bug as well, confirmed that the patch worked for me. I am also using "language switcher extended" module.
Comment #11
juagarc4 commentedPatch #2 is working for me on Core 10.3.1.
I am also using "language switcher extended" module.
Comment #12
szeidlerIs this a Core responsibility or just a bug in "Language Switcher Extended" module? I'm happily merging a fix for it into the module, if it's handled wrong there.
Comment #16
jan kellermann commented@szeidler Here you returns NULL and this triggers the WPOD. Maybe you could try to return [] and filter out the block if link-array is empty later until this issue is solved.
Comment #17
jan kellermann commentedI just created an issue fork and commitet tests and bugfixes for 10.3 and 11.x and created MRs.
1st commit in each branch is the PHP-Unit test which fails (status code 500).
2nd commit in each branch is the fix for this bug (test for type array).
A 2nd test is added in 1st commit to validate that the switch-block is not shown if $result is NULL after alter()-function.
Comment #18
jan kellermann commentedGeneral consideration: The function determines the links for the language switcher from the negotiators. If no links are returned here, the entire block is omitted.
The aim must be to enable this behavior with the alter() function as well. So far, an empty array after the alter() function leads to a language switcher block without links. To hide the block, NULL must be returned. (This must also be permitted in the alter() function; simple typing via array() is then no longer possible - see patches for API file).
The previous patches are based on allowing NULL. Another variant would be that the block is not rendered if the array is empty after the alter() function. This would eliminate the zero setting and also the display of an empty block.
Would that be a more appropriate solution?
Comment #19
smustgrave commentedBoth MRs appear to have failures. Would recommend just sticking with 11.x MR for now.
Comment #23
jan kellermann commentedThe MR for D11 is fixed.
The MR for D10.3 fails because of #3466822, but the commit should be okay.
But in general see comment 18
Comment #25
jan kellermann commentedI added branch 3362713-11.x for D11 with proposals from comment 18. See interdiff.
I think this is the cleanest way.
Comment #26
ankitv18 commentedConsidering the implemented condition I'm assuming that $result is either empty or null or other non-array value and if it is non-array then no use to iterate through array_filter.
I would suggest return false; if non-array value is there would help.
Keeping this in review so that other reviewer have something else in the mind.
Comment #31
smustgrave commentedI wouldn't recommend opening MR for other branches as it will just make more work to keep up and could get kicked back by the review bot.
If the 11.x doesn't apply to the other branches the committer will mark it for backport. But very seldom do the MRs themselves get merged.
Comment #34
smustgrave commentedLeft some comments/question on the MR
Comment #35
jan kellermann commentedTwo questions are still open in MR that need to be answered by core developers. The other suggestions have been adopted.
Comment #36
jan kellermann commentedCan I support to close the two remaing questions?
Comment #37
jan kellermann commentedComment #38
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #39
jan kellermann commentedI added the missing
declare(strict_types=1);and updated the MR.The failed tests are not related to this issue.
Perhaps someone can decide the two open questions. I don't see any need for action on either point.
Comment #40
sagarmohite0031 commentedHello,
Getting error while applying patch.
Attaching error screenshot.
Comment #41
jan kellermann commented@sagarmohite0031 I updated the fork. Please test again.
Comment #42
thhafner commentedTested on 11.x with the language switcher use case in the initial issue description and functioning as expected.
Comment #43
thhafner commentedComment #45
quietone commentedI started to review this but then decided to make the changes myself. I changed comments to remove the reference to the issue number, as that is not our practice and git can tell use the issue number. I moved the test code block to the end of the test method as was able to remove some clean up line, and the added an very simple example to the hook_language_switch_links_alter.
Setting to review for someone to check those changes.
And Un-assigning per Assigning ownership of a Drupal core issue.
Comment #46
quietone commentedComment #47
smustgrave commentedLeft small comments on MR
If you are another contributor eager to jump in, please allow the previous poster at least 48 hours to respond to feedback first, so they have the opportunity to finish what they started!
Comment #48
jan kellermann commentedAdded new Hooks Implementation. Please review and feedback.
Comment #49
smustgrave commentedUnresolved 1 thread for the committer to see.
New API will need a CR also and noticed that section was removed from the issue summary. Wouldn't recommend removing headers from the summary, even if they aren't used
Comment #50
jan kellermann commentedI changed summary and created CR.
Comment #51
smustgrave commentedRe-unresolving the same thread, want the committers to see
Comment #52
smustgrave commentedThink this needs a core-committer to decide on open thread, so leaving it open and moving to RTBC as rest seems fine.
Comment #53
alexpottI think we should be logging an error when $results is altered to a non array type. Even though that used to work before the security issue fix it is non interoperable with other hook implementation.
Also I think we should change the code to obey the interface and return NULL if the array filter results in $results being empty.
Furthermore I think we need a try {} finally {} here to ensure that $this->negotiatedLanguages is reset regardless of what we do.
Comment #54
alexpottHere's how I think the code should look:
Comment #55
alexpottI guess we could change
trigger_error('A language_switch_links hook implementation has changed $result to a non-array.', E_USER_WARNING);to a proper deprecation and say that in Drupal 12 this will cause an exception when we remove the check...Comment #56
yi_jiang commented#2 works for D10 so far. Failed on Drupal11.
I have created a new patch for D11, so far works for ~11.2.
Comment #57
jan kellermann commentedIt seems that block's behavior has changed so that it is also displayed when NULL is returned (see failed test). It seems that another way to hide the block must be found, and thus the issue #3358576 for language_switcher_extended and this core issue are obsolete.
Comment #59
znak commentedPatch for 11.3.13
Comment #60
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.