Merge branch 'REL1_41' into REL1_41-qw

这个提交包含在:
WaitSpring 2024-03-29 10:18:15 +08:00
当前提交 685aa4c622
共有 20 个文件被更改,包括 114 次插入39 次删除

查看文件

@ -5,10 +5,17 @@ PHP 8.1 workboard: https://phabricator.wikimedia.org/tag/php_8.1_support/
PHP 8.2 workboard: https://phabricator.wikimedia.org/tag/php_8.2_support/
PHP 8.3 workboard: https://phabricator.wikimedia.org/tag/php_8.3_support/
== MediaWiki 1.41.1 ==
== MediaWiki 1.41.2 ==
THIS IS NOT A RELEASE YET
=== Changes since MediaWiki 1.41.1 ===
* Localisation updates.
== MediaWiki 1.41.1 ==
This is a security and maintenance release of the MediaWiki 1.41 branch.
=== Changes since MediaWiki 1.41.0 ===
* Localisation updates.
* CategoryViewer: Fix "count(): Argument #1 ($value) must be of type
@ -33,7 +40,6 @@ THIS IS NOT A RELEASE YET
* (T355530) filerepo: Fix img_major_mime for files with a non-standard
extensions.
* (T355530) MimeAnalyzer: Add @since to isValidMajorMimeType.
* Update wikimedia/parsoid to 0.18.1.
* (T352554) ZhConverter: Fix language variant fallback chain.
* (T347541) Add 'maxlength' and 'minlength' support to HTMLTextAreaField.
* (T357668) Parser::getExternalLinkAttribs: Don't set rel attribute to null.
@ -52,6 +58,16 @@ THIS IS NOT A RELEASE YET
* (T292237, T317451) build: Restore Doxygen output for MediaWiki release tags.
* (T324903) HistoryPager: Add #[AllowDynamicProperties].
* (T360850) Update Apache config syntax in .htaccess files.
* Update wikimedia/parsoid to 0.18.2.
* docs: Remove use of $IP from mwdocgen.php.
* (T317451) build: Restore Doxygen output for MediaWiki release tags (take 3).
* docs: Set stable permalink on markdown files.
* (T360608) WebRequest: detectServer appends default ports that should be
omitted.
* (T357019) allow maintenance/deleteBatch.php to accept page ID.
* (T355538 CVE-2024-PENDING) XSS in edit summary parser.
* (T357760, CVE-2024-PENDING) Denial of service vector via GET request to
Special:MovePage on pages with thousands of subpages.
== MediaWiki 1.41.0 ==

查看文件

@ -1,4 +1,4 @@
Hooks
Hooks {#hooks}
=====
## Introduction

查看文件

@ -1,4 +1,4 @@
Language
Language {#language}
=======
The Language object handles all readable text produced by the software.

查看文件

@ -1,3 +1,6 @@
LinkCache {#linkcache}
========
The LinkCache class maintains a list of article titles and the information about
whether or not the article exists in the database. This is used to mark up links
when displaying a page. If the same link appears more than once on any page,
@ -11,7 +14,7 @@ purposes of updating the link tables. This application is now deprecated.
To create a batch, you can use the following code:
~~~{.php}
```php
$pages = [ 'Main Page', 'Project:Help', /* ... */ ];
$titles = [];
@ -22,4 +25,4 @@ foreach( $pages as $page ){
$linkBatchFactory = MediaWikiServices::getInstance()->getLinkBatchFactory();
$batch = $linkBatchFactory->newLinkBatch( $titles );
$batch->execute();
~~~
```

查看文件

@ -1,4 +1,4 @@
Skins
Skins {#skin}
=======
## Core Skins

查看文件

@ -1,3 +1,6 @@
Title {#title}
========
The MediaWiki software's "Title" class represents article titles, which are used
for many purposes: as the human-readable text title of the article, in the URL
used to access the article, the wikitext link to the article, the key into the

查看文件

@ -1,4 +1,5 @@
# ContentHandler
ContentHandler {#contenthandler}
=====
The *ContentHandler* facility adds support for arbitrary content types on wiki pages, instead of relying on wikitext for everything. It was introduced in MediaWiki 1.21.

查看文件

@ -1,4 +1,5 @@
# Database Access
Database Access {#database}
=====
*Some information about database access in MediaWiki. By Tim Starling, January 2006.*

查看文件

@ -1,4 +1,4 @@
Magic Words
Magic Words {#magicword}
====================================
Magic words are localizable keywords used in wikitext. They are used for many

查看文件

@ -1,4 +1,4 @@
Memcached
Memcached {#memcached}
====================================
MediaWiki has optional support for memcached, a "high-performance,
@ -251,5 +251,3 @@ Special:Recentchanges (feed):
calling Special:Recentchanges?action=purge&feed=rss,
Special:Recentchanges?action=purge&feed=atom,
but note need $wgGroupPermissions[...]['purge'] permission.
... more to come ...

查看文件

@ -1,4 +1,4 @@
PageUpdater
PageUpdater {#pageupdater}
===========
This document provides an overview of the usage of PageUpdater and DerivedPageDataUpdater.

查看文件

@ -1,4 +1,4 @@
Schema
Schema {#schema}
======
The most up-to-date schema for the tables in the database

查看文件

@ -1,4 +1,4 @@
Sitelist
Sitelist {#sitelist}
========
This document describes the XML format used to represent information about external sites known to a MediaWiki installation. This information about external sites is used to allow "inter-wiki" links, cross-language navigation, as well as close integration via direct access to the other site's web API or even directly to their database.

@ -1 +1 @@
Subproject commit 4f42839986eb2a30fb40aa16748ee0ab78cff3d6
Subproject commit 2b07d85d9053df0df37a130679d6c26897162fea

查看文件

@ -64,6 +64,8 @@ class CommentParser {
/** @var int The maximum number of digits in a marker ID */
private const MAX_ID_SIZE = 7;
/** @var string Prefix for marker. ' and " included to break attributes (T355538) */
private const MARKER_PREFIX = "\x1B\"'";
/**
* @param LinkRenderer $linkRenderer
@ -143,7 +145,7 @@ class CommentParser {
public function finalize( $comments ) {
$this->flushLinkBatches();
return preg_replace_callback(
'/\x1b([0-9]{' . self::MAX_ID_SIZE . '})/',
'/' . self::MARKER_PREFIX . '([0-9]{' . self::MAX_ID_SIZE . '})/',
function ( $m ) {
$callback = $this->links[(int)$m[1]] ?? null;
if ( $callback ) {
@ -450,7 +452,7 @@ class CommentParser {
throw new \RuntimeException( 'Too many links in comment batch' );
}
$this->links[] = $callback;
return sprintf( "\x1b%0" . self::MAX_ID_SIZE . 'd', $nextId );
return sprintf( self::MARKER_PREFIX . "%0" . self::MAX_ID_SIZE . 'd', $nextId );
}
/**

查看文件

@ -33,7 +33,7 @@ use Wikimedia\Rdbms\IDatabase;
*
* @since 1.35 (also backported to 1.33.3 and 1.34.1)
*/
define( 'MW_VERSION', '1.41.0' );
define( 'MW_VERSION', '1.41.1' );
/** @{
* Obsolete IDatabase::makeList() constants

查看文件

@ -288,7 +288,7 @@ class WebRequest {
$port = $stdPort;
} elseif ( $parts[1] === false ) {
if ( isset( $_SERVER['SERVER_PORT'] ) ) {
$port = $_SERVER['SERVER_PORT'];
$port = intval( $_SERVER['SERVER_PORT'] );
} // else leave it as $stdPort
} else {
$port = $parts[1];

查看文件

@ -972,12 +972,13 @@ class SpecialMovePage extends UnlistedSpecialPage {
* @param Title $title Page being moved.
*/
private function showSubpages( $title ) {
$maximumMovedPages = $this->getConfig()->get( MainConfigNames::MaximumMovedPages );
$nsHasSubpages = $this->nsInfo->hasSubpages( $title->getNamespace() );
$subpages = $title->getSubpages();
$subpages = $title->getSubpages( $maximumMovedPages + 1 );
$count = $subpages instanceof TitleArrayFromResult ? $subpages->count() : 0;
$titleIsTalk = $title->isTalkPage();
$subpagesTalk = $title->getTalkPage()->getSubpages();
$subpagesTalk = $title->getTalkPage()->getSubpages( $maximumMovedPages + 1 );
$countTalk = $subpagesTalk instanceof TitleArrayFromResult ? $subpagesTalk->count() : 0;
$totalCount = $count + $countTalk;
@ -1008,7 +1009,19 @@ class SpecialMovePage extends UnlistedSpecialPage {
return;
}
$out->addWikiMsg( $wikiMsg, $this->getLanguage()->formatNum( $pagecount ) );
$maximumMovedPages = $this->getConfig()->get( MainConfigNames::MaximumMovedPages );
if ( $pagecount > $maximumMovedPages ) {
$subpages = $this->truncateSubpagesList( $subpages );
// TODO: Replace with a message key once this is uploaded to Gerrit. This is hardcoded to avoid
// having the i18n rebuilt for all deployments due to this security patch.
$out->addWikiTextAsInterface(
"The first $maximumMovedPages {{PLURAL:$maximumMovedPages|subpage|subpages}} " .
( $noSubpageMsg ? 'for this page' : 'for the corresponding talk page' ) . ' are shown below.'
);
} else {
$out->addWikiMsg( $wikiMsg, $this->getLanguage()->formatNum( $pagecount ) );
}
$out->addHTML( "<ul>\n" );
$linkBatch = $this->linkBatchFactory->newLinkBatch( $subpages );
@ -1023,6 +1036,17 @@ class SpecialMovePage extends UnlistedSpecialPage {
$out->addHTML( "</ul>\n" );
}
private function truncateSubpagesList( iterable $subpages ): array {
$returnArray = [];
foreach ( $subpages as $subpage ) {
$returnArray[] = $subpage;
if ( count( $returnArray ) >= $this->getConfig()->get( MainConfigNames::MaximumMovedPages ) ) {
break;
}
}
return $returnArray;
}
/**
* Return an array of subpages beginning with $search that this special page will accept.
*

查看文件

@ -1,7 +1,7 @@
<?php
/**
* Deletes a batch of pages.
* Usage: php deleteBatch.php [-u <user>] [-r <reason>] [-i <interval>] [listfile]
* Usage: php deleteBatch.php [-u <user>] [-r <reason>] [-i <interval>] [--by-id] [listfile]
* where
* [listfile] is a file where each line contains the title of a page to be
* deleted, standard input is used if listfile is not given.
@ -47,6 +47,7 @@ class DeleteBatch extends Maintenance {
$this->addOption( 'u', 'User to perform deletion', false, true );
$this->addOption( 'r', 'Reason to delete page', false, true );
$this->addOption( 'i', 'Interval to sleep (in seconds) between deletions' );
$this->addOption( 'by-id', 'Delete by page ID instead of by page name', false, false );
$this->addArg( 'listfile', 'File with titles to delete, separated by newlines. ' .
'If not given, stdin will be used.', false );
}
@ -60,6 +61,7 @@ class DeleteBatch extends Maintenance {
$username = $this->getOption( 'u', false );
$reason = $this->getOption( 'r', '' );
$interval = $this->getOption( 'i', 0 );
$byId = $this->hasOption( 'by-id' );
if ( $username === false ) {
$user = User::newSystemUser( 'Delete page script', [ 'steal' => true ] );
@ -93,26 +95,36 @@ class DeleteBatch extends Maintenance {
if ( $line == '' ) {
continue;
}
$title = Title::newFromText( $line );
if ( $title === null ) {
$this->output( "Invalid title '$line' on line $linenum\n" );
continue;
if ( $byId === false ) {
$target = Title::newFromText( $line );
if ( $target === null ) {
$this->output( "Invalid title '$line' on line $linenum\n" );
continue;
}
if ( !$target->exists() ) {
$this->output( "Skipping nonexistent page '$line'\n" );
continue;
}
} else {
$target = Title::newFromID( (int)$line );
if ( $target === null ) {
$this->output( "Invalid page ID '$line' on line $linenum\n" );
continue;
}
if ( !$target->exists() ) {
$this->output( "Skipping nonexistent page ID '$line'\n" );
continue;
}
}
if ( !$title->exists() ) {
$this->output( "Skipping nonexistent page '$line'\n" );
continue;
}
$this->output( $title->getPrefixedText() );
if ( $title->getNamespace() === NS_FILE ) {
if ( $target->getNamespace() === NS_FILE ) {
$img = $repoGroup->findFile(
$title, [ 'ignoreRedirect' => true ]
$target, [ 'ignoreRedirect' => true ]
);
if ( $img && $img->isLocal() && !$img->deleteFile( $reason, $user ) ) {
$this->output( " FAILED to delete associated file..." );
}
}
$page = $wikiPageFactory->newFromTitle( $title );
$page = $wikiPageFactory->newFromTitle( $target );
$delPage = $delPageFactory->newDeletePage( $page, $user );
$status = $delPage
->forceImmediate( true )

查看文件

@ -53,13 +53,28 @@ class WebRequestTest extends MediaWikiIntegrationTestCase {
],
'Host header with secure'
],
[
'http://x',
[
'HTTP_HOST' => 'x:80',
],
'Host header with port'
],
[
'http://x',
[
'HTTP_HOST' => 'x',
'SERVER_PORT' => 80,
],
'Default SERVER_PORT',
'Default SERVER_PORT as int',
],
[
'http://x',
[
'HTTP_HOST' => 'x',
'SERVER_PORT' => '80',
],
'Default SERVER_PORT as string',
],
[
'http://x',