Page MenuHomePhabricator

PHP Warning: "count(): Parameter must be an array or an object that implements Countable" on AbuseFilter history with PHP7
Closed, ResolvedPublic

Description

On Logstash, I noticed this error happen for AbuseFilter history. Steps to reproduce:

  • Go to cswiki and enable PHP7 (doesn't happen with HHVM)
  • Go here

The user cannot notice any error, but the following is logged on Logstash:

message
PHP Warning: count(): Parameter must be an array or an object that implements Countable
stacktrace
#0 /srv/mediawiki/php-1.33.0-wmf.16/extensions/AbuseFilter/includes/AbuseFilter.php(3061): MWExceptionHandler::handleError(integer, string, string, integer, array)
#1 /srv/mediawiki/php-1.33.0-wmf.16/extensions/AbuseFilter/includes/Views/AbuseFilterViewDiff.php(377): AbuseFilter::formatAction(string, NULL)
#2 /srv/mediawiki/php-1.33.0-wmf.16/extensions/AbuseFilter/includes/Views/AbuseFilterViewDiff.php(345): AbuseFilterViewDiff->stringifyActions(array)
#3 /srv/mediawiki/php-1.33.0-wmf.16/extensions/AbuseFilter/includes/Views/AbuseFilterViewDiff.php(41): AbuseFilterViewDiff->formatDiff()
#4 /srv/mediawiki/php-1.33.0-wmf.16/extensions/AbuseFilter/includes/special/SpecialAbuseFilter.php(122): AbuseFilterViewDiff->show()
#5 /srv/mediawiki/php-1.33.0-wmf.16/includes/specialpage/SpecialPage.php(569): SpecialAbuseFilter->execute(string)
#6 /srv/mediawiki/php-1.33.0-wmf.16/includes/specialpage/SpecialPageFactory.php(558): SpecialPage->run(string)
#7 /srv/mediawiki/php-1.33.0-wmf.16/includes/MediaWiki.php(288): MediaWiki\Special\SpecialPageFactory->executePath(Title, RequestContext)
#8 /srv/mediawiki/php-1.33.0-wmf.16/includes/MediaWiki.php(862): MediaWiki->performRequest()
#9 /srv/mediawiki/php-1.33.0-wmf.16/includes/MediaWiki.php(517): MediaWiki->main()
#10 /srv/mediawiki/php-1.33.0-wmf.16/index.php(42): MediaWiki->run()
#11 /srv/mediawiki/w/index.php(3): require(string)
#12 {main}

It almost surely has something to do with T203587 and subtasks.

Event Timeline

Alright, this has indeed to do with the linked task and friends. The root cause is that, in some specific cases, we stored a NULL in abuse_filter_history for completely empty throttle parameters. Such null ultimately gets passed to formatAction, which expects an array and thus fails. Newer entries don't have this problem, although maybe instead of adding compatibility code we could fix broken entries in normalizeThrottleParameters (T209565). We should first identify what specifically caused params to be null. Then the fix would be pretty simple: query, unserialize, replace NULL with an empty array (memo: check if this is really the best choice), serialize and store it back. Will investigate further.

OK, so yes, this is the same case as "$totallyEmpty" in normalizeThrottleParameters. This happened for filters which only had comma separated values in throttle groups before switching to OOUI (rEABFb825e396b5ee15e65505f0eb6a3571cf9d48eba3). With the switch, some things were changed and ultimately we got to this line with $throttleGroups being NULL, and thus array_merge returned null. This caused throttle parameters to be wiped away. Of note, changing the DB could help make these lines useless as well.

Note that, AFAICS, this only happened twice in all WMF wikis (one filter in cswiki and one in kowiki).

Change 489705 had a related patch set uploaded (by Daimona Eaytoy; owner: Daimona Eaytoy):
[mediawiki/extensions/AbuseFilter@master] Beautify old, broken abuse_filter_history rows

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

Change 489705 had a related patch set uploaded (by Daimona Eaytoy; owner: Daimona Eaytoy):
[mediawiki/extensions/AbuseFilter@master] Beautify old, broken abuse_filter_history rows

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

Change 489705 merged by jenkins-bot:
[mediawiki/extensions/AbuseFilter@master] Beautify old, broken abuse_filter_history rows

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

(Waiting for the script to be executed)

Krinkle subscribed.

Untagging from PHP 7.2 support as this isn't a blocking issue. No behaviour was changed in PHP 7.2. It just emits a warning for a pre-existing issue.