/** mediawiki-1.37.0\includes\parser\CoreParserFunctions.php
* Override the title of the page when viewed, provided we've been given a
* title which will normalise to the canonical title
*
* @param Parser $parser Parent parser
* @param string $text Desired title text
* @param string $uarg
* @return string
*/
public static function displaytitle( $parser, $text = '', $uarg = '' ) {
global $wgRestrictDisplayTitle;
static $magicWords = null;
if ( $magicWords === null ) {
$magicWords = $parser->getMagicWordFactory()->newArray(
[ 'displaytitle_noerror', 'displaytitle_noreplace' ] );
}
$arg = $magicWords->matchStartToEnd( $uarg );
// parse a limited subset of wiki markup (just the single quote items)
$text = $parser->doQuotes( $text );
// remove stripped text (e.g. the UNIQ-QINU stuff) that was generated by tag extensions/whatever
$text = $parser->killMarkers( $text );
// list of disallowed tags for DISPLAYTITLE
// these will be escaped even though they are allowed in normal wiki text
$bad = [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'blockquote', 'ol', 'ul', 'li', 'hr',
'table', 'tr', 'th', 'td', 'dl', 'dd', 'caption', 'p', 'ruby', 'rb', 'rt', 'rtc', 'rp', 'br' ];
// disallow some styles that could be used to bypass $wgRestrictDisplayTitle
if ( $wgRestrictDisplayTitle ) {
$htmlTagsCallback = static function ( &$params ) {
$decoded = Sanitizer::decodeTagAttributes( $params );
if ( isset( $decoded['style'] ) ) {
// this is called later anyway, but we need it right now for the regexes below to be safe
// calling it twice doesn't hurt
$decoded['style'] = Sanitizer::checkCss( $decoded['style'] );
if ( preg_match( '/(display|user-select|visibility)\s*:/i', $decoded['style'] ) ) {
$decoded['style'] = '/* attempt to bypass $wgRestrictDisplayTitle */';
}
}
$params = Sanitizer::safeEncodeTagAttributes( $decoded );
};
} else {
$htmlTagsCallback = null;
}
// only requested titles that normalize to the actual title are allowed through
// if $wgRestrictDisplayTitle is true (it is by default)
// mimic the escaping process that occurs in OutputPage::setPageTitle
$text = Sanitizer::normalizeCharReferences( Sanitizer::removeHTMLtags(
$text,
$htmlTagsCallback,
[],
[],
$bad
) );
$title = Title::newFromText( Sanitizer::stripAllTags( $text ) );
if ( !$wgRestrictDisplayTitle ||
( $title instanceof Title
&& !$title->hasFragment()
&& $title->equals( $parser->getTitle() ) )
) {
$old = $parser->getOutput()->getProperty( 'displaytitle' );
if ( $old === false || $arg !== 'displaytitle_noreplace' ) {
$parser->getOutput()->setDisplayTitle( $text );
}
if ( $old !== false && $old !== $text && !$arg ) {
$converter = self::getTargetLanguageConverter( $parser );
return '<span class="error">' .
wfMessage( 'duplicate-displaytitle',
// Message should be parsed, but these params should only be escaped.
$converter->markNoConversion( wfEscapeWikiText( $old ) ),
$converter->markNoConversion( wfEscapeWikiText( $text ) )
)->inContentLanguage()->text() .
'</span>';
} else {
return '';
}
} else {
$parser->getOutput()->addWarning(
wfMessage( 'restricted-displaytitle',
// Message should be parsed, but this param should only be escaped.
wfEscapeWikiText( $text )
)->text()
);
$parser->addTrackingCategory( 'restricted-displaytitle-ignored' );
}
}