Page MenuHomePhabricator

PHP Notice: Trying to access array offset on value of type bool (in OutputPage.php)
Closed, ResolvedPublicPRODUCTION ERROR

Description

Error
normalized_message
[{reqId}] {exception_url}   PHP Notice: Trying to access array offset on value of type bool
exception.trace
from /srv/mediawiki/php-1.39.0-wmf.28/includes/OutputPage.php(2134)
#0 /srv/mediawiki/php-1.39.0-wmf.28/includes/OutputPage.php(2134): MWExceptionHandler::handleError(integer, string, string, integer, array)
#1 /srv/mediawiki/php-1.39.0-wmf.28/includes/OutputPage.php(2232): OutputPage->addParserOutputMetadata(ParserOutput)
#2 /srv/mediawiki/php-1.39.0-wmf.28/includes/page/Article.php(773): OutputPage->addParserOutput(ParserOutput, array)
#3 /srv/mediawiki/php-1.39.0-wmf.28/includes/page/Article.php(621): Article->doOutputFromParserCache(ParserOutput, OutputPage, array)
#4 /srv/mediawiki/php-1.39.0-wmf.28/includes/page/Article.php(528): Article->generateContentOutput(User, ParserOptions, integer, OutputPage, array)
#5 /srv/mediawiki/php-1.39.0-wmf.28/includes/actions/ViewAction.php(78): Article->view()
#6 /srv/mediawiki/php-1.39.0-wmf.28/includes/MediaWiki.php(542): ViewAction->show()
#7 /srv/mediawiki/php-1.39.0-wmf.28/includes/MediaWiki.php(322): MediaWiki->performAction(Article, Title)
#8 /srv/mediawiki/php-1.39.0-wmf.28/includes/MediaWiki.php(904): MediaWiki->performRequest()
#9 /srv/mediawiki/php-1.39.0-wmf.28/includes/MediaWiki.php(562): MediaWiki->main()
#10 /srv/mediawiki/php-1.39.0-wmf.28/index.php(50): MediaWiki->run()
#11 /srv/mediawiki/php-1.39.0-wmf.28/index.php(46): wfIndexMain()
#12 /srv/mediawiki/w/index.php(3): require(string)
#13 {main}
Notes
  • Happening on private wikis
  • Started 2022-09-05
  • All errors from PHP 7.4

Event Timeline

ssastry added subscribers: dpifke, Krinkle, ssastry.

The code in questions was added in https://gerrit.wikimedia.org/r/c/mediawiki/core/+/570788 by @dpifke for T123582. While it is easy to check for the failure of wfParseUrl and do something, @Krinkle may have a better sense of what the right failure handling should be there.

@ssastry The code appears to be recovering to the "correct" behaviour in that the subsequent foreach loop ignores null values, and the officewiki page connected to this task's error sample shows the correct output (view-source, includes the preconnect link for upload.wikimedia.org).

I'm guesing we're dealing with a ParserOutput object that reports an image for which the URL (formatted by FileBackend) is invalid according to wfParseUrl. I can't think of why that would be though.

The correlation with PHP 7.4 is consistent with PHP 7.4 deprecating silent tolerance of array access on boolean false - as confirmed via https://3v4l.org/VOJLq. Note that this is is only a deprecation warning at this time, it still proceeds and returns null.

I would suggest moving the check earlier, to be on the return value instead of later in the loop. And perhaps add a diagnostic $logger->warning() to figure out whether the invalid value is something we want to tolerate or whether there is a genuine bug here that we need to deal with. It's quite possible that the bug is so common that a local repo would expose it.

I've gone ahead and done exactly that. Stock localhost with InstantCommons and [[File:Example.jpg]] on the Main Page, which I already had prior to today. And after a git-pull and merely enabling $wgImagePreconnect = true;, I immediately get:

PHP Notice: Trying to access array offset on value of type bool in /var/www/html/w/includes/OutputPage.php on line 2134

Debugging:

OutputPage.php
            $repoGroup = MediaWikiServices::getInstance()->getRepoGroup();
            $repoGroup->forEachForeignRepo( static function ( $repo ) use ( &$preconnect ) {
-               $preconnect[] = wfParseUrl( $repo->getZoneUrl( 'thumb' ) )['host'];
+               var_dump($repo->getZoneUrl( 'thumb' ));
+               $preconnect[] = wfParseUrl( $repo->getZoneUrl( 'thumb' ) );
            } );
-           $preconnect[] = wfParseUrl( $repoGroup->getLocalRepo()->getZoneUrl( 'thumb' ) )['host'];
+           var_dump($repoGroup->getLocalRepo()->getZoneUrl( 'thumb' ));
+           $preconnect[] = wfParseUrl( $repoGroup->getLocalRepo()->getZoneUrl( 'thumb' ) );
+           var_dump( $preconnect );
-           foreach ( $preconnect as $host ) {
+           foreach ( $preconnect as $url ) {
+               $host = $url['host'] ?? null;
-               if ( $host ) {
+               if ( !$host ) {
+                   var_dump( $url );
+                   continue;
+               } else {
                    $this->addLink( [ 'rel' => 'preconnect', 'href' => '//' . $host ] );
                    break;
                }
string(52) "https://upload.wikimedia.org/wikipedia/commons/thumb"
string(15) "/w/images/thumb"
array(2) {
  [0]=>
  array(4) {
    ["scheme"]=>
    string(5) "https"
    ["host"]=>
    string(20) "upload.wikimedia.org"
    ["path"]=>
    string(24) "/wikipedia/commons/thumb"
    ["delimiter"]=>
    string(3) "://"
  }
  [1]=>
  bool(false)
}

And, for the purposes of this particular snippet of code, our developer stock local setup is quite similar to what we have on officewiki (compared to other prod wikis).

$ mwscript eval.php nlwiki
> $repoGroup = MediaWiki\MediaWikiServices::getInstance()->getRepoGroup();
> echo $repoGroup->getLocalRepo()->getZoneUrl( 'thumb' );
//upload.wikimedia.org/wikipedia/nl/thumb

[16:52 UTC] krinkle at mwmaint1002.eqiad.wmnet in ~
$ mwscript eval.php officewiki
> $repoGroup = MediaWiki\MediaWikiServices::getInstance()->getRepoGroup();
> echo $repoGroup->getLocalRepo()->getZoneUrl( 'thumb' );
/w/thumb_handler.php

So not so much an invalid URL as a relative URL without a host.

Change 830908 had a related patch set uploaded (by Krinkle; author: Krinkle):

[mediawiki/core@master] OutputPage: Fix undefined `['host']` in ImagePreconnect code

https://gerrit.wikimedia.org/r/830908

Krinkle triaged this task as High priority.
Krinkle added a project: Performance-Team.

Change 830908 merged by jenkins-bot:

[mediawiki/core@master] OutputPage: Fix undefined `['host']` in ImagePreconnect code

https://gerrit.wikimedia.org/r/830908

Krinkle renamed this task from PHP Notice: Trying to access array offset on value of type bool to PHP Notice: Trying to access array offset on value of type bool (in OutputPage.php).Sep 14 2022, 12:32 PM

Change 884336 had a related patch set uploaded (by Paladox; author: Krinkle):

[mediawiki/core@REL1_39] OutputPage: Fix undefined `['host']` in ImagePreconnect code

https://gerrit.wikimedia.org/r/884336

Change 884339 had a related patch set uploaded (by Paladox; author: Krinkle):

[mediawiki/core@REL1_38] OutputPage: Fix undefined `['host']` in ImagePreconnect code

https://gerrit.wikimedia.org/r/884339

Change 884340 had a related patch set uploaded (by Paladox; author: Krinkle):

[mediawiki/core@REL1_35] OutputPage: Fix undefined `['host']` in ImagePreconnect code

https://gerrit.wikimedia.org/r/884340

Change 884336 merged by jenkins-bot:

[mediawiki/core@REL1_39] OutputPage: Fix undefined `['host']` in ImagePreconnect code

https://gerrit.wikimedia.org/r/884336

Change 884340 merged by jenkins-bot:

[mediawiki/core@REL1_35] OutputPage: Fix undefined `['host']` in ImagePreconnect code

https://gerrit.wikimedia.org/r/884340

Change 884339 merged by jenkins-bot:

[mediawiki/core@REL1_38] OutputPage: Fix undefined `['host']` in ImagePreconnect code

https://gerrit.wikimedia.org/r/884339