Work around change in SimpleXMLElement behavior introduced in PHP 7.3.17
authorC. Scott Ananian <cscott@cscott.net>
Thu, 30 Apr 2020 22:10:43 +0000 (18:10 -0400)
committerReedy <reedy@wikimedia.org>
Thu, 30 Apr 2020 23:15:58 +0000 (23:15 +0000)
Upstream bug reports of the behavior change introduced in PHP 7.3.17 (and
applied to PHP 7.4 branch as well):
https://bugs.php.net/bug.php?id=79528
https://bugs.php.net/bug.php?id=79485

The reponsible commit in PHP was https://github.com/php/php-src/pull/5246

This was a "bug fix" in the sense that SimpleXML used to discard the
attributes on the namespace elements, which look like this:
     <namespace key="-2" case="first-letter">Media</namespace>
SimpleXML used to return this as a string "Media" instead of a
SimpleXMLElement... but ExportTest (inadvertently?) depended on that
behavior.

In any case, if we iterate over SimpleXMLElement::children() we always
get SimpleXMLElements, not "sometimes strings", and so our code will
correct correctly on PHP below 7.3.17 and above, regardless of how PHP
decides to handle this "bug".

Bug: T250568
Change-Id: I9c2cb6a86fd6e8023c1979ec6838071a87a7bcea
(cherry picked from commit 7f1ad7d9848782d025bad63149e058964fc37c97)

tests/phpunit/includes/ExportTest.php

index a5d3570..73f2337 100644 (file)
@@ -42,14 +42,11 @@ class ExportTest extends MediaWikiLangTestCase {
                /**
                 * Check namespaces match xml
                 */
-               $xmlNamespaces = (array)$xmlObject->siteinfo->namespaces->namespace;
-               $xmlNamespaces = str_replace( ' ', '_', $xmlNamespaces );
-               unset( $xmlNamespaces[ '@attributes' ] );
-               foreach ( $xmlNamespaces as &$namespaceObject ) {
-                       if ( is_object( $namespaceObject ) ) {
-                               $namespaceObject = '';
-                       }
+               foreach ( $xmlObject->siteinfo->namespaces->children() as $namespace ) {
+                       // Get the text content of the SimpleXMLElement
+                       $xmlNamespaces[] = (string)$namespace;
                }
+               $xmlNamespaces = str_replace( ' ', '_', $xmlNamespaces );
 
                $actualNamespaces = (array)$wgContLang->getNamespaces();
                $actualNamespaces = array_values( $actualNamespaces );