Version in base suite: 1.31.4-1~deb10u1 Base version: mediawiki_1.31.4-1~deb10u1 Target version: mediawiki_1.31.6-1~deb10u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/m/mediawiki/mediawiki_1.31.4-1~deb10u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/m/mediawiki/mediawiki_1.31.6-1~deb10u1.dsc RELEASE-NOTES-1.31 | 29 +++++++ debian/changelog | 7 + debian/patches/0002-PermissionManager-doesn-t-exist-in-1.33-so-we-cannot.patch | 28 ------- debian/patches/series | 1 extensions/SyntaxHighlight_GeSHi/README | 6 - includes/DefaultSettings.php | 2 includes/GlobalFunctions.php | 12 +++ includes/api/ApiEditPage.php | 14 +++ includes/api/i18n/en.json | 1 includes/api/i18n/qqq.json | 1 includes/installer/Installer.php | 1 includes/jobqueue/JobQueueRedis.php | 6 - includes/libs/MultiHttpClient.php | 2 includes/libs/mime/MimeAnalyzer.php | 2 includes/libs/objectcache/RedisBagOStuff.php | 5 - includes/libs/rdbms/database/Database.php | 8 +- includes/libs/rdbms/database/DatabasePostgres.php | 8 +- includes/libs/rdbms/field/PostgresField.php | 2 includes/media/FormatMetadata.php | 18 +++- includes/specials/SpecialBrokenRedirects.php | 1 includes/specials/SpecialDoubleRedirects.php | 1 includes/specials/SpecialListredirects.php | 1 includes/specials/SpecialLonelypages.php | 1 includes/specials/SpecialPasswordReset.php | 9 ++ includes/specials/SpecialRedirect.php | 4 - includes/specials/SpecialUncategorizedimages.php | 23 ++++- includes/specials/SpecialUncategorizedpages.php | 1 includes/specials/SpecialUnusedcategories.php | 5 + includes/specials/SpecialUnusedtemplates.php | 5 + includes/specials/SpecialWithoutinterwiki.php | 1 maintenance/addSite.php | 12 +-- tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php | 40 ++++++++++ tests/phpunit/includes/specials/SpecialUncategorizedcategoriesTest.php | 1 33 files changed, 180 insertions(+), 78 deletions(-) diff -Nru mediawiki-1.31.4/RELEASE-NOTES-1.31 mediawiki-1.31.6/RELEASE-NOTES-1.31 --- mediawiki-1.31.4/RELEASE-NOTES-1.31 2019-10-07 18:04:13.000000000 +0000 +++ mediawiki-1.31.6/RELEASE-NOTES-1.31 2019-12-19 13:40:52.000000000 +0000 @@ -1,3 +1,32 @@ +== MediaWiki 1.31.6 == + +This is a security and maintenance release of the MediaWiki 1.31 branch. + +=== Changes since MediaWiki 1.31.5 === +* (T181658) Do not insert page titles into querycache.qc_value. +* (T206013) Suppress errors when reading invalid XML file properties. +* (T237931) Remove references to pg_attrdef.adsrc in Postgres code. +* Use correct value for 'sslmode' in DatabasePostgres. +* (T232866) Fix support for HTTP/2 in MultiHttpClient. +* (T227461) Stop calling deprecated Redis delete functions. +* (T239561) Mark options as requiring parameters in addSite.php. +* (T239734) Replace deprecated lSize with lLen in Redis code. +* (T192134) SECURITY: Do not allow user scripts on Special:PasswordReset. +* (T239428) ApiEditPage: Test for bad redirect targets. +* (T233342) rdbms: Log debug message traces as 'exception.trace' instead of + 'trace'. +* (T226751) media: Log and fail gracefully on invalid EXIF coordinates. +* (T212067) Work around PHP bug in parse_url. + +== MediaWiki 1.31.5 == + +This is a maintenance release of the MediaWiki 1.31 branch. + +=== Changes since MediaWiki 1.31.4 === +* Fix extra newlines in installer. +* Followup T230402, PermissionManager doesn't exist until 1.33, so fix the + backported patches to use User::isAllowed() instead. + == MediaWiki 1.31.4 == This is a security and maintenance release of the MediaWiki 1.31 branch. diff -Nru mediawiki-1.31.4/debian/changelog mediawiki-1.31.6/debian/changelog --- mediawiki-1.31.4/debian/changelog 2019-10-11 21:59:46.000000000 +0000 +++ mediawiki-1.31.6/debian/changelog 2019-12-19 21:03:58.000000000 +0000 @@ -1,3 +1,10 @@ +mediawiki (1:1.31.6-1~deb10u1) buster-security; urgency=medium + + * New upstream version 1.31.6 (security release), fixing + CVE-2019-19709. + + -- Kunal Mehta Thu, 19 Dec 2019 13:03:58 -0800 + mediawiki (1:1.31.4-1~deb10u1) buster-security; urgency=medium * New upstream version 1.31.4 (security release), fixing diff -Nru mediawiki-1.31.4/debian/patches/0002-PermissionManager-doesn-t-exist-in-1.33-so-we-cannot.patch mediawiki-1.31.6/debian/patches/0002-PermissionManager-doesn-t-exist-in-1.33-so-we-cannot.patch --- mediawiki-1.31.4/debian/patches/0002-PermissionManager-doesn-t-exist-in-1.33-so-we-cannot.patch 2019-10-11 21:59:46.000000000 +0000 +++ mediawiki-1.31.6/debian/patches/0002-PermissionManager-doesn-t-exist-in-1.33-so-we-cannot.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -From: Reedy -Date: Sat, 12 Oct 2019 00:36:47 +0100 -Origin: https://gerrit.wikimedia.org/r/#/c/mediawiki/core/+/542626/ -Subject: PermissionManager doesn't exist in 1.33, so we cannot use it in 1.31 - -Followup T230402, PermissionManager doesn't exist until 1.33, so fix the -backported patches to use User::isAllowed() instead. - -Change-Id: Ia73bf71293d67f97fb5086ffc0384307568d4d43 ---- - includes/specials/SpecialRedirect.php | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/includes/specials/SpecialRedirect.php b/includes/specials/SpecialRedirect.php -index 7eba0de..27176c4 100644 ---- a/includes/specials/SpecialRedirect.php -+++ b/includes/specials/SpecialRedirect.php -@@ -81,9 +81,7 @@ class SpecialRedirect extends FormSpecialPage { - // Message: redirect-not-exists - return Status::newFatal( $this->getMessagePrefix() . '-not-exists' ); - } -- if ( $user->isHidden() && !MediaWikiServices::getInstance()->getPermissionManager() -- ->userHasRight( $this->getUser(), 'hideuser' ) -- ) { -+ if ( $user->isHidden() && !$this->getUser()->isAllowed( 'hideuser' ) ) { - throw new PermissionsError( null, [ 'badaccess-group0' ] ); - } - $userpage = Title::makeTitle( NS_USER, $username ); diff -Nru mediawiki-1.31.4/debian/patches/series mediawiki-1.31.6/debian/patches/series --- mediawiki-1.31.4/debian/patches/series 2019-10-11 21:59:46.000000000 +0000 +++ mediawiki-1.31.6/debian/patches/series 2019-12-19 21:03:45.000000000 +0000 @@ -1,2 +1 @@ pear-phail-fail-shebang.diff -0002-PermissionManager-doesn-t-exist-in-1.33-so-we-cannot.patch diff -Nru mediawiki-1.31.4/extensions/SyntaxHighlight_GeSHi/README mediawiki-1.31.6/extensions/SyntaxHighlight_GeSHi/README --- mediawiki-1.31.4/extensions/SyntaxHighlight_GeSHi/README 2019-06-07 17:02:21.000000000 +0000 +++ mediawiki-1.31.6/extensions/SyntaxHighlight_GeSHi/README 2019-12-19 13:40:55.000000000 +0000 @@ -6,8 +6,8 @@ == Requirements == -This version of the extension has been tested with Pygments 1.6, 2.0.2 and -MediaWiki 1.25 as of 2015-06-19. To get releases of this extension compatible +This version of the extension has been tested with Pygments 2.2.0 and +MediaWiki 1.31. To get releases of this extension compatible with earlier versions of MediaWiki, visit: https://www.mediawiki.org/wiki/Special:ExtensionDistributor/SyntaxHighlight_GeSHi @@ -18,7 +18,7 @@ wfLoadExtension( 'SyntaxHighlight_GeSHi' ); -By default, this extension will use a bundled copy of Pygments 2.0.2. If you +By default, this extension will use a bundled copy of Pygments 2.2.0. If you would like to use a different copy of the library, you can set $wgPygmentizePath to point to the path to the 'pygmentize' binary. diff -Nru mediawiki-1.31.4/includes/DefaultSettings.php mediawiki-1.31.6/includes/DefaultSettings.php --- mediawiki-1.31.4/includes/DefaultSettings.php 2019-10-07 18:04:13.000000000 +0000 +++ mediawiki-1.31.6/includes/DefaultSettings.php 2019-12-19 13:38:12.000000000 +0000 @@ -71,7 +71,7 @@ * MediaWiki version number * @since 1.2 */ -$wgVersion = '1.31.4'; +$wgVersion = '1.31.6'; /** * Name of the site. It must be changed in LocalSettings.php diff -Nru mediawiki-1.31.4/includes/GlobalFunctions.php mediawiki-1.31.6/includes/GlobalFunctions.php --- mediawiki-1.31.4/includes/GlobalFunctions.php 2019-10-07 18:04:13.000000000 +0000 +++ mediawiki-1.31.6/includes/GlobalFunctions.php 2019-12-19 13:38:12.000000000 +0000 @@ -811,6 +811,18 @@ Wikimedia\suppressWarnings(); $bits = parse_url( $url ); Wikimedia\restoreWarnings(); + + // T212067: PHP < 5.6.28, 7.0.0–7.0.12, and HHVM (all relevant versions) screw up parsing + // the query part of pathless URLs + if ( isset( $bits['host'] ) && strpos( $bits['host'], '?' ) !== false ) { + list( $host, $query ) = explode( '?', $bits['host'], 2 ); + $bits['host'] = $host; + $bits['query'] = $query + . ( $bits['path'] ?? '' ) + . ( isset( $bits['query'] ) ? '?' . $bits['query'] : '' ); + unset( $bits['path'] ); + } + // parse_url() returns an array without scheme for some invalid URLs, e.g. // parse_url("%0Ahttp://example.com") == [ 'host' => '%0Ahttp', 'path' => 'example.com' ] if ( !$bits || !isset( $bits['scheme'] ) ) { diff -Nru mediawiki-1.31.4/includes/api/ApiEditPage.php mediawiki-1.31.6/includes/api/ApiEditPage.php --- mediawiki-1.31.4/includes/api/ApiEditPage.php 2019-10-07 18:03:52.000000000 +0000 +++ mediawiki-1.31.6/includes/api/ApiEditPage.php 2019-12-19 13:37:33.000000000 +0000 @@ -70,6 +70,20 @@ ]; $titleObj = $newTitle; + + // T239428: Check whether the new title is valid + if ( $titleObj->isExternal() || !$titleObj->canExist() ) { + $redirValues[count( $redirValues ) - 1]['to'] = $titleObj->getFullText(); + $this->dieWithError( + [ + 'apierror-edit-invalidredirect', + Message::plaintextParam( $oldTitle->getPrefixedText() ), + Message::plaintextParam( $titleObj->getFullText() ), + ], + 'edit-invalidredirect', + [ 'redirects' => $redirValues ] + ); + } } ApiResult::setIndexedTagName( $redirValues, 'r' ); diff -Nru mediawiki-1.31.4/includes/api/i18n/en.json mediawiki-1.31.6/includes/api/i18n/en.json --- mediawiki-1.31.4/includes/api/i18n/en.json 2019-10-07 18:04:13.000000000 +0000 +++ mediawiki-1.31.6/includes/api/i18n/en.json 2019-12-19 13:38:12.000000000 +0000 @@ -1694,6 +1694,7 @@ "apierror-databaseerror": "[$1] Database query error.", "apierror-deletedrevs-param-not-1-2": "The $1 parameter cannot be used in modes 1 or 2.", "apierror-deletedrevs-param-not-3": "The $1 parameter cannot be used in mode 3.", + "apierror-edit-invalidredirect": "Cannot edit $1 while following redirects, as target $2 is not valid.", "apierror-emptynewsection": "Creating empty new sections is not possible.", "apierror-emptypage": "Creating new, empty pages is not allowed.", "apierror-exceptioncaught": "[$1] Exception caught: $2", diff -Nru mediawiki-1.31.4/includes/api/i18n/qqq.json mediawiki-1.31.6/includes/api/i18n/qqq.json --- mediawiki-1.31.4/includes/api/i18n/qqq.json 2019-10-07 18:04:13.000000000 +0000 +++ mediawiki-1.31.6/includes/api/i18n/qqq.json 2019-12-19 13:38:12.000000000 +0000 @@ -1582,6 +1582,7 @@ "apierror-databaseerror": "{{doc-apierror}}\n\nParameters:\n* $1 - Exception log ID code. This is meaningless to the end user, but can be used by people with access to the logs to easily find the logged error.", "apierror-deletedrevs-param-not-1-2": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.\n\nSee also:\n* {{msg-mw|apihelp-query+deletedrevs-extended-description}}", "apierror-deletedrevs-param-not-3": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.\n\nSee also:\n* {{msg-mw|apihelp-query+deletedrevs-extended-description}}", + "apierror-edit-invalidredirect": "{{doc-apierror}}\n\nParameters:\n* $1 - Redirect being edited\n* $2 - Target of the redirect that cannot be edited.", "apierror-emptynewsection": "{{doc-apierror}}", "apierror-emptypage": "{{doc-apierror}}", "apierror-exceptioncaught": "{{doc-apierror}}\n\nParameters:\n* $1 - Exception log ID code. This is meaningless to the end user, but can be used by people with access to the logs to easily find the logged error.\n* $2 - Exception message, which may end with punctuation. Probably in English.", diff -Nru mediawiki-1.31.4/includes/installer/Installer.php mediawiki-1.31.6/includes/installer/Installer.php --- mediawiki-1.31.4/includes/installer/Installer.php 2019-10-07 18:04:13.000000000 +0000 +++ mediawiki-1.31.6/includes/installer/Installer.php 2019-12-19 13:38:12.000000000 +0000 @@ -697,6 +697,7 @@ 'enableSectionEditLinks' => false, 'unwrap' => true, ] ); + $html = Parser::stripOuterParagraph( $html ); } catch ( MediaWiki\Services\ServiceDisabledException $e ) { $html = ' ' . htmlspecialchars( $text ); } diff -Nru mediawiki-1.31.4/includes/jobqueue/JobQueueRedis.php mediawiki-1.31.6/includes/jobqueue/JobQueueRedis.php --- mediawiki-1.31.4/includes/jobqueue/JobQueueRedis.php 2019-10-07 18:04:13.000000000 +0000 +++ mediawiki-1.31.6/includes/jobqueue/JobQueueRedis.php 2019-12-19 13:38:12.000000000 +0000 @@ -132,7 +132,7 @@ protected function doGetSize() { $conn = $this->getConnection(); try { - return $conn->lSize( $this->getQueueKey( 'l-unclaimed' ) ); + return $conn->lLen( $this->getQueueKey( 'l-unclaimed' ) ); } catch ( RedisException $e ) { $this->throwRedisException( $conn, $e ); } @@ -502,7 +502,7 @@ $keys[] = $this->getQueueKey( $prop ); } - $ok = ( $conn->delete( $keys ) !== false ); + $ok = ( $conn->del( $keys ) !== false ); $conn->sRem( $this->getGlobalKey( 's-queuesWithJobs' ), $this->encodeQueueName() ); return $ok; @@ -607,7 +607,7 @@ try { $conn->multi( Redis::PIPELINE ); foreach ( $types as $type ) { - $conn->lSize( $this->getQueueKey( 'l-unclaimed', $type ) ); + $conn->lLen( $this->getQueueKey( 'l-unclaimed', $type ) ); } $res = $conn->exec(); if ( is_array( $res ) ) { diff -Nru mediawiki-1.31.4/includes/libs/MultiHttpClient.php mediawiki-1.31.6/includes/libs/MultiHttpClient.php --- mediawiki-1.31.4/includes/libs/MultiHttpClient.php 2019-10-07 18:04:13.000000000 +0000 +++ mediawiki-1.31.6/includes/libs/MultiHttpClient.php 2019-12-19 13:38:12.000000000 +0000 @@ -375,7 +375,7 @@ } $length = strlen( $header ); $matches = []; - if ( preg_match( "/^(HTTP\/1\.[01]) (\d{3}) (.*)/", $header, $matches ) ) { + if ( preg_match( "/^(HTTP\/(?:1\.[01]|2)) (\d{3}) (.*)/", $header, $matches ) ) { $req['response']['code'] = (int)$matches[2]; $req['response']['reason'] = trim( $matches[3] ); return $length; diff -Nru mediawiki-1.31.4/includes/libs/mime/MimeAnalyzer.php mediawiki-1.31.6/includes/libs/mime/MimeAnalyzer.php --- mediawiki-1.31.4/includes/libs/mime/MimeAnalyzer.php 2019-10-07 18:04:13.000000000 +0000 +++ mediawiki-1.31.6/includes/libs/mime/MimeAnalyzer.php 2019-12-19 13:38:12.000000000 +0000 @@ -760,7 +760,9 @@ /** * look for XML formats (XHTML and SVG) */ + Wikimedia\suppressWarnings(); $xml = new XmlTypeCheck( $file ); + Wikimedia\restoreWarnings(); if ( $xml->wellFormed ) { $xmlTypes = $this->xmlTypes; if ( isset( $xmlTypes[$xml->getRootElement()] ) ) { diff -Nru mediawiki-1.31.4/includes/libs/objectcache/RedisBagOStuff.php mediawiki-1.31.6/includes/libs/objectcache/RedisBagOStuff.php --- mediawiki-1.31.4/includes/libs/objectcache/RedisBagOStuff.php 2019-10-07 18:04:13.000000000 +0000 +++ mediawiki-1.31.6/includes/libs/objectcache/RedisBagOStuff.php 2019-12-19 13:38:12.000000000 +0000 @@ -21,8 +21,9 @@ */ /** - * Redis-based caching module for redis server >= 2.6.12 + * Redis-based caching module for redis server >= 2.6.12 and phpredis >= 2.2.4 * + * @see https://github.com/phpredis/phpredis/blob/d310ed7c8/Changelog.md * @note Avoid use of Redis::MULTI transactions for twemproxy support * * @ingroup Cache @@ -135,7 +136,7 @@ return false; } try { - $conn->delete( $key ); + $conn->del( $key ); // Return true even if the key didn't exist $result = true; } catch ( RedisException $e ) { diff -Nru mediawiki-1.31.4/includes/libs/rdbms/database/Database.php mediawiki-1.31.6/includes/libs/rdbms/database/Database.php --- mediawiki-1.31.4/includes/libs/rdbms/database/Database.php 2019-10-07 18:04:13.000000000 +0000 +++ mediawiki-1.31.6/includes/libs/rdbms/database/Database.php 2019-12-19 13:38:12.000000000 +0000 @@ -2235,7 +2235,7 @@ if ( preg_match( '/(^|\s)(DISTINCT|JOIN|ON|AS)(\s|$)/i', $name ) !== 0 ) { $this->queryLogger->warning( __METHOD__ . ": use of subqueries is not supported this way.", - [ 'trace' => ( new RuntimeException() )->getTraceAsString() ] + [ 'exception' => new RuntimeException() ] ); return $name; @@ -3994,7 +3994,7 @@ $fname . ': lost connection to {dbserver}; reconnected', [ 'dbserver' => $this->getServer(), - 'trace' => ( new RuntimeException() )->getTraceAsString() + 'exception' => new RuntimeException() ] ); } catch ( DBConnectionError $e ) { @@ -4510,8 +4510,8 @@ */ public function __clone() { $this->connLogger->warning( - "Cloning " . static::class . " is not recomended; forking connection:\n" . - ( new RuntimeException() )->getTraceAsString() + "Cloning " . static::class . " is not recommended; forking connection", + [ 'exception' => new RuntimeException() ] ); if ( $this->isOpen() ) { diff -Nru mediawiki-1.31.4/includes/libs/rdbms/database/DatabasePostgres.php mediawiki-1.31.6/includes/libs/rdbms/database/DatabasePostgres.php --- mediawiki-1.31.4/includes/libs/rdbms/database/DatabasePostgres.php 2019-10-07 18:04:13.000000000 +0000 +++ mediawiki-1.31.6/includes/libs/rdbms/database/DatabasePostgres.php 2019-12-19 13:38:12.000000000 +0000 @@ -119,7 +119,7 @@ $connectVars['port'] = (int)$this->port; } if ( $this->flags & self::DBO_SSL ) { - $connectVars['sslmode'] = 1; + $connectVars['sslmode'] = 'require'; } $this->connectString = $this->makeConnectionString( $connectVars ); @@ -816,7 +816,7 @@ . ' WHERE relkind = \'r\'' . ' AND nspname = ' . $this->addQuotes( $this->getCoreSchema() ) . ' AND relname = ' . $this->addQuotes( $oldName ) - . ' AND adsrc LIKE \'nextval(%\'', + . ' AND pg_get_expr(adbin, adrelid) LIKE \'nextval(%\'', $fname ); $row = $this->fetchObject( $res ); @@ -851,10 +851,10 @@ } $oid = $this->fetchObject( $res )->oid; - $res = $this->query( 'SELECT adsrc FROM pg_attribute a' + $res = $this->query( 'SELECT pg_get_expr(adbin, adrelid) AS adsrc FROM pg_attribute a' . ' JOIN pg_attrdef d ON (a.attrelid=d.adrelid and a.attnum=d.adnum)' . " WHERE a.attrelid = $oid" - . ' AND adsrc LIKE \'nextval(%\'', + . ' AND pg_get_expr(adbin, adrelid) LIKE \'nextval(%\'', $fname ); $row = $this->fetchObject( $res ); diff -Nru mediawiki-1.31.4/includes/libs/rdbms/field/PostgresField.php mediawiki-1.31.6/includes/libs/rdbms/field/PostgresField.php --- mediawiki-1.31.4/includes/libs/rdbms/field/PostgresField.php 2019-10-07 18:03:53.000000000 +0000 +++ mediawiki-1.31.6/includes/libs/rdbms/field/PostgresField.php 2019-12-01 19:49:55.000000000 +0000 @@ -17,7 +17,7 @@ SELECT attnotnull, attlen, conname AS conname, atthasdef, - adsrc, + pg_get_expr(adbin, adrelid) AS adsrc, COALESCE(condeferred, 'f') AS deferred, COALESCE(condeferrable, 'f') AS deferrable, CASE WHEN typname = 'int2' THEN 'smallint' diff -Nru mediawiki-1.31.4/includes/media/FormatMetadata.php mediawiki-1.31.6/includes/media/FormatMetadata.php --- mediawiki-1.31.4/includes/media/FormatMetadata.php 2019-10-07 18:04:13.000000000 +0000 +++ mediawiki-1.31.6/includes/media/FormatMetadata.php 2019-12-19 13:38:12.000000000 +0000 @@ -1400,11 +1400,16 @@ * Format a coordinate value, convert numbers from floating point * into degree minute second representation. * - * @param int $coord Degrees, minutes and seconds - * @param string $type Latitude or longitude (for if its a NWS or E) - * @return mixed A floating point number or whatever we were fed + * @param float|string $coord Expected to be a number or numeric string in degrees + * @param string $type "latitude" or "longitude" + * @return string */ private function formatCoords( $coord, $type ) { + if ( !is_numeric( $coord ) ) { + wfDebugLog( 'exif', __METHOD__ . ": \"$coord\" is not a number" ); + return (string)$coord; + } + $ref = ''; if ( $coord < 0 ) { $nCoord = -$coord; @@ -1414,7 +1419,7 @@ $ref = 'W'; } } else { - $nCoord = $coord; + $nCoord = (float)$coord; if ( $type === 'latitude' ) { $ref = 'N'; } elseif ( $type === 'longitude' ) { @@ -1423,13 +1428,14 @@ } $deg = floor( $nCoord ); - $min = floor( ( $nCoord - $deg ) * 60.0 ); - $sec = round( ( ( $nCoord - $deg ) - $min / 60 ) * 3600, 2 ); + $min = floor( ( $nCoord - $deg ) * 60 ); + $sec = round( ( ( $nCoord - $deg ) * 60 - $min ) * 60, 2 ); $deg = $this->formatNum( $deg ); $min = $this->formatNum( $min ); $sec = $this->formatNum( $sec ); + // Note the default message "$1° $2′ $3″ $4" ignores the 5th parameter return $this->msg( 'exif-coordinate-format', $deg, $min, $sec, $ref, $coord )->text(); } diff -Nru mediawiki-1.31.4/includes/specials/SpecialBrokenRedirects.php mediawiki-1.31.6/includes/specials/SpecialBrokenRedirects.php --- mediawiki-1.31.4/includes/specials/SpecialBrokenRedirects.php 2019-10-07 18:01:31.000000000 +0000 +++ mediawiki-1.31.6/includes/specials/SpecialBrokenRedirects.php 2019-12-19 13:36:52.000000000 +0000 @@ -63,7 +63,6 @@ 'fields' => [ 'namespace' => 'p1.page_namespace', 'title' => 'p1.page_title', - 'value' => 'p1.page_title', 'rd_namespace', 'rd_title', 'rd_fragment', diff -Nru mediawiki-1.31.4/includes/specials/SpecialDoubleRedirects.php mediawiki-1.31.6/includes/specials/SpecialDoubleRedirects.php --- mediawiki-1.31.4/includes/specials/SpecialDoubleRedirects.php 2019-10-07 18:01:31.000000000 +0000 +++ mediawiki-1.31.6/includes/specials/SpecialDoubleRedirects.php 2019-12-19 13:36:52.000000000 +0000 @@ -64,7 +64,6 @@ 'fields' => [ 'namespace' => 'pa.page_namespace', 'title' => 'pa.page_title', - 'value' => 'pa.page_title', 'b_namespace' => 'pb.page_namespace', 'b_title' => 'pb.page_title', diff -Nru mediawiki-1.31.4/includes/specials/SpecialListredirects.php mediawiki-1.31.6/includes/specials/SpecialListredirects.php --- mediawiki-1.31.4/includes/specials/SpecialListredirects.php 2019-10-07 18:01:31.000000000 +0000 +++ mediawiki-1.31.6/includes/specials/SpecialListredirects.php 2019-12-19 13:36:52.000000000 +0000 @@ -53,7 +53,6 @@ 'tables' => [ 'p1' => 'page', 'redirect', 'p2' => 'page' ], 'fields' => [ 'namespace' => 'p1.page_namespace', 'title' => 'p1.page_title', - 'value' => 'p1.page_title', 'rd_namespace', 'rd_title', 'rd_fragment', diff -Nru mediawiki-1.31.4/includes/specials/SpecialLonelypages.php mediawiki-1.31.6/includes/specials/SpecialLonelypages.php --- mediawiki-1.31.4/includes/specials/SpecialLonelypages.php 2019-10-07 18:01:31.000000000 +0000 +++ mediawiki-1.31.6/includes/specials/SpecialLonelypages.php 2019-12-19 13:36:52.000000000 +0000 @@ -79,7 +79,6 @@ 'fields' => [ 'namespace' => 'page_namespace', 'title' => 'page_title', - 'value' => 'page_title' ], 'conds' => $conds, 'join_conds' => $joinConds diff -Nru mediawiki-1.31.4/includes/specials/SpecialPasswordReset.php mediawiki-1.31.6/includes/specials/SpecialPasswordReset.php --- mediawiki-1.31.4/includes/specials/SpecialPasswordReset.php 2019-10-07 18:04:13.000000000 +0000 +++ mediawiki-1.31.6/includes/specials/SpecialPasswordReset.php 2019-12-19 13:38:12.000000000 +0000 @@ -74,6 +74,15 @@ parent::checkExecutePermissions( $user ); } + /** + * @param string $par + */ + public function execute( $par ) { + $out = $this->getOutput(); + $out->disallowUserJs(); + parent::execute( $par ); + } + protected function getFormFields() { $resetRoutes = $this->getConfig()->get( 'PasswordResetRoutes' ); $a = []; diff -Nru mediawiki-1.31.4/includes/specials/SpecialRedirect.php mediawiki-1.31.6/includes/specials/SpecialRedirect.php --- mediawiki-1.31.4/includes/specials/SpecialRedirect.php 2019-10-07 18:03:53.000000000 +0000 +++ mediawiki-1.31.6/includes/specials/SpecialRedirect.php 2019-12-19 13:37:33.000000000 +0000 @@ -81,9 +81,7 @@ // Message: redirect-not-exists return Status::newFatal( $this->getMessagePrefix() . '-not-exists' ); } - if ( $user->isHidden() && !MediaWikiServices::getInstance()->getPermissionManager() - ->userHasRight( $this->getUser(), 'hideuser' ) - ) { + if ( $user->isHidden() && !$this->getUser()->isAllowed( 'hideuser' ) ) { throw new PermissionsError( null, [ 'badaccess-group0' ] ); } $userpage = Title::makeTitle( NS_USER, $username ); diff -Nru mediawiki-1.31.4/includes/specials/SpecialUncategorizedimages.php mediawiki-1.31.6/includes/specials/SpecialUncategorizedimages.php --- mediawiki-1.31.4/includes/specials/SpecialUncategorizedimages.php 2019-10-07 18:01:31.000000000 +0000 +++ mediawiki-1.31.6/includes/specials/SpecialUncategorizedimages.php 2019-12-19 13:36:52.000000000 +0000 @@ -45,17 +45,28 @@ return false; } + function getOrderFields() { + return [ 'title' ]; + } + function getQueryInfo() { return [ 'tables' => [ 'page', 'categorylinks' ], - 'fields' => [ 'namespace' => 'page_namespace', + 'fields' => [ + 'namespace' => 'page_namespace', 'title' => 'page_title', - 'value' => 'page_title' ], - 'conds' => [ 'cl_from IS NULL', + ], + 'conds' => [ + 'cl_from IS NULL', 'page_namespace' => NS_FILE, - 'page_is_redirect' => 0 ], - 'join_conds' => [ 'categorylinks' => [ - 'LEFT JOIN', 'cl_from=page_id' ] ] + 'page_is_redirect' => 0, + ], + 'join_conds' => [ + 'categorylinks' => [ + 'LEFT JOIN', + 'cl_from=page_id', + ], + ], ]; } diff -Nru mediawiki-1.31.4/includes/specials/SpecialUncategorizedpages.php mediawiki-1.31.6/includes/specials/SpecialUncategorizedpages.php --- mediawiki-1.31.4/includes/specials/SpecialUncategorizedpages.php 2019-10-07 18:01:31.000000000 +0000 +++ mediawiki-1.31.6/includes/specials/SpecialUncategorizedpages.php 2019-12-19 13:36:52.000000000 +0000 @@ -52,7 +52,6 @@ 'fields' => [ 'namespace' => 'page_namespace', 'title' => 'page_title', - 'value' => 'page_title' ], // default for page_namespace is all content namespaces (if requestedNamespace is false) // otherwise, page_namespace is requestedNamespace diff -Nru mediawiki-1.31.4/includes/specials/SpecialUnusedcategories.php mediawiki-1.31.6/includes/specials/SpecialUnusedcategories.php --- mediawiki-1.31.4/includes/specials/SpecialUnusedcategories.php 2019-10-07 18:03:53.000000000 +0000 +++ mediawiki-1.31.6/includes/specials/SpecialUnusedcategories.php 2019-12-19 13:37:33.000000000 +0000 @@ -37,13 +37,16 @@ return $this->msg( 'unusedcategoriestext' )->parseAsBlock(); } + function getOrderFields() { + return [ 'title' ]; + } + public function getQueryInfo() { return [ 'tables' => [ 'page', 'categorylinks' ], 'fields' => [ 'namespace' => 'page_namespace', 'title' => 'page_title', - 'value' => 'page_title' ], 'conds' => [ 'cl_from IS NULL', diff -Nru mediawiki-1.31.4/includes/specials/SpecialUnusedtemplates.php mediawiki-1.31.6/includes/specials/SpecialUnusedtemplates.php --- mediawiki-1.31.4/includes/specials/SpecialUnusedtemplates.php 2019-10-07 18:01:31.000000000 +0000 +++ mediawiki-1.31.6/includes/specials/SpecialUnusedtemplates.php 2019-12-19 13:36:52.000000000 +0000 @@ -46,13 +46,16 @@ return false; } + function getOrderFields() { + return [ 'title' ]; + } + public function getQueryInfo() { return [ 'tables' => [ 'page', 'templatelinks' ], 'fields' => [ 'namespace' => 'page_namespace', 'title' => 'page_title', - 'value' => 'page_title' ], 'conds' => [ 'page_namespace' => NS_TEMPLATE, diff -Nru mediawiki-1.31.4/includes/specials/SpecialWithoutinterwiki.php mediawiki-1.31.6/includes/specials/SpecialWithoutinterwiki.php --- mediawiki-1.31.4/includes/specials/SpecialWithoutinterwiki.php 2019-10-07 18:01:31.000000000 +0000 +++ mediawiki-1.31.6/includes/specials/SpecialWithoutinterwiki.php 2019-12-19 13:36:52.000000000 +0000 @@ -87,7 +87,6 @@ 'fields' => [ 'namespace' => 'page_namespace', 'title' => 'page_title', - 'value' => 'page_title' ], 'conds' => [ 'll_title IS NULL', diff -Nru mediawiki-1.31.4/maintenance/addSite.php mediawiki-1.31.6/maintenance/addSite.php --- mediawiki-1.31.4/maintenance/addSite.php 2019-10-07 18:04:15.000000000 +0000 +++ mediawiki-1.31.6/maintenance/addSite.php 2019-12-19 13:38:14.000000000 +0000 @@ -21,13 +21,13 @@ $this->addArg( 'globalid', 'The global id of the site to add, e.g. "wikipedia".', true ); $this->addArg( 'group', 'In which group this site should be sorted in.', true ); - $this->addOption( 'language', 'The language code of the site, e.g. "de".' ); - $this->addOption( 'interwiki-id', 'The interwiki ID of the site.' ); - $this->addOption( 'navigation-id', 'The navigation ID of the site.' ); + $this->addOption( 'language', 'The language code of the site, e.g. "de".', false, true ); + $this->addOption( 'interwiki-id', 'The interwiki ID of the site.', false, true ); + $this->addOption( 'navigation-id', 'The navigation ID of the site.', false, true ); $this->addOption( 'pagepath', 'The URL to pages of this site, e.g.' . - ' https://example.com/wiki/\$1.' ); - $this->addOption( 'filepath', 'The URL to files of this site, e.g. https://example - .com/w/\$1.' ); + ' https://example.com/wiki/\$1.', false, true ); + $this->addOption( 'filepath', 'The URL to files of this site, e.g. https://example' . + '.com/w/\$1.', false, true ); parent::__construct(); } diff -Nru mediawiki-1.31.4/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php mediawiki-1.31.6/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php --- mediawiki-1.31.4/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php 2018-12-12 23:21:38.000000000 +0000 +++ mediawiki-1.31.6/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php 2019-12-19 13:29:22.000000000 +0000 @@ -152,6 +152,46 @@ 'invalid://test/', false ], + // T212067 + [ + '//evil.com?example.org/foo/bar', + [ + 'scheme' => '', + 'delimiter' => '//', + 'host' => 'evil.com', + 'query' => 'example.org/foo/bar', + ] + ], + [ + '//evil.com?example.org/foo/bar?baz#quux', + [ + 'scheme' => '', + 'delimiter' => '//', + 'host' => 'evil.com', + 'query' => 'example.org/foo/bar?baz', + 'fragment' => 'quux', + ] + ], + [ + '//evil.com?example.org?baz#quux', + [ + 'scheme' => '', + 'delimiter' => '//', + 'host' => 'evil.com', + 'query' => 'example.org?baz', + 'fragment' => 'quux', + ] + ], + [ + '//evil.com?example.org#quux', + [ + 'scheme' => '', + 'delimiter' => '//', + 'host' => 'evil.com', + 'query' => 'example.org', + 'fragment' => 'quux', + ] + ], ]; } } diff -Nru mediawiki-1.31.4/tests/phpunit/includes/specials/SpecialUncategorizedcategoriesTest.php mediawiki-1.31.6/tests/phpunit/includes/specials/SpecialUncategorizedcategoriesTest.php --- mediawiki-1.31.4/tests/phpunit/includes/specials/SpecialUncategorizedcategoriesTest.php 2019-10-07 18:03:55.000000000 +0000 +++ mediawiki-1.31.6/tests/phpunit/includes/specials/SpecialUncategorizedcategoriesTest.php 2019-12-19 13:37:36.000000000 +0000 @@ -21,7 +21,6 @@ 'fields' => [ 'namespace' => 'page_namespace', 'title' => 'page_title', - 'value' => 'page_title', ], 'conds' => [ 0 => 'cl_from IS NULL',