Merge branch 'REL1_41' into REL1_41-qw
这个提交包含在:
当前提交
685aa4c622
|
@ -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',
|
||||
|
|
正在加载...
在新工单中引用