public $currentRevisionCache;
/**
- * @var bool Recursive call protection.
+ * @var bool|string Recursive call protection.
* This variable should be treated as if it were private.
*/
public $mInParse = false;
// Since we're not really outputting HTML, decode the entities and
// then re-encode the things that need hiding inside HTML comments.
$limitReport = htmlspecialchars_decode( $limitReport );
- Hooks::run( 'ParserLimitReport', [ $this, &$limitReport ] );
+ // Run deprecated hook
+ Hooks::run( 'ParserLimitReport', [ $this, &$limitReport ], '1.22' );
// Sanitize for comment. Note '‐' in the replacement is U+2010,
// which looks much like the problematic '-'.
* @return string
*/
public function doTableStuff( $text ) {
-
$lines = StringUtils::explode( "\n", $text );
$out = '';
$td_history = []; # Is currently a td tag open?
* @return string
*/
public function internalParse( $text, $isMain = true, $frame = false ) {
-
$origText = $text;
// Avoid PHP 7.1 warning from passing $this by reference
* @return string
*/
public function replaceExternalLinks( $text ) {
-
$bits = preg_split( $this->mExtLinkBracketedRegex, $text, -1, PREG_SPLIT_DELIM_CAPTURE );
if ( $bits === false ) {
throw new MWException( "PCRE needs to be compiled with "
$link = $origLink;
}
- $noforce = ( substr( $origLink, 0, 1 ) !== ':' );
- if ( !$noforce ) {
- # Strip off leading ':'
- $link = substr( $link, 1 );
- }
-
$unstrip = $this->mStripState->unstripNoWiki( $link );
$nt = is_string( $unstrip ) ? Title::newFromText( $unstrip ) : null;
if ( $nt === null ) {
$ns = $nt->getNamespace();
$iw = $nt->getInterwiki();
+ $noforce = ( substr( $origLink, 0, 1 ) !== ':' );
+
if ( $might_be_img ) { # if this is actually an invalid link
if ( $ns == NS_FILE && $noforce ) { # but might be an image
$found = false;
$wasblank = ( $text == '' );
if ( $wasblank ) {
$text = $link;
+ if ( !$noforce ) {
+ # Strip off leading ':'
+ $text = substr( $text, 1 );
+ }
} else {
# T6598 madness. Handle the quotes only if they come from the alternate part
# [[Lista d''e paise d''o munno]] -> <a href="...">Lista d''e paise d''o munno</a>
}
$s = rtrim( $s . $prefix );
- $s .= trim( $trail, "\n" ) == '' ? '': $prefix . $trail;
+ $s .= trim( $trail, "\n" ) == '' ? '' : $prefix . $trail;
continue;
}
* @return string The text of the template
*/
public function braceSubstitution( $piece, $frame ) {
-
// Flags
// $text has been filled
list( $callback, $flags ) = $this->mFunctionHooks[$function];
- # Workaround for PHP bug 35229 and similar
- if ( !is_callable( $callback ) ) {
- throw new MWException( "Tag hook for $function is not callable\n" );
- }
-
// Avoid PHP 7.1 warning from passing $this by reference
$parser = $this;
* @return array
*/
public function argSubstitution( $piece, $frame ) {
-
$error = false;
$parts = $piece['parts'];
$nameWithSpaces = $frame->expand( $piece['title'] );
}
if ( isset( $this->mTagHooks[$name] ) ) {
- # Workaround for PHP bug 35229 and similar
- if ( !is_callable( $this->mTagHooks[$name] ) ) {
- throw new MWException( "Tag hook for $name is not callable\n" );
- }
$output = call_user_func_array( $this->mTagHooks[$name],
[ $content, $attributes, $this, $frame ] );
} elseif ( isset( $this->mFunctionTagHooks[$name] ) ) {
list( $callback, ) = $this->mFunctionTagHooks[$name];
- if ( !is_callable( $callback ) ) {
- throw new MWException( "Tag hook for $name is not callable\n" );
- }
// Avoid PHP 7.1 warning from passing $this by reference
$parser = $this;
* @return string
*/
public function doDoubleUnderscore( $text ) {
-
# The position of __TOC__ needs to be recorded
$mw = MagicWord::get( 'toc' );
if ( $mw->match( $text ) ) {
$toc = Linker::tocList( $toc, $this->mOptions->getUserLangObj() );
$this->mOutput->setTOCHTML( $toc );
$toc = self::TOC_START . $toc . self::TOC_END;
- $this->mOutput->addModules( 'mediawiki.toc' );
}
if ( $isMain ) {
# which may corrupt this parser instance via its wfMessage()->text() call-
# Signatures
- $sigText = $this->getUserSig( $user );
- $text = strtr( $text, [
- '~~~~~' => $d,
- '~~~~' => "$sigText $d",
- '~~~' => $sigText
- ] );
+ if ( strpos( $text, '~~~' ) !== false ) {
+ $sigText = $this->getUserSig( $user );
+ $text = strtr( $text, [
+ '~~~~~' => $d,
+ '~~~~' => "$sigText $d",
+ '~~~' => $sigText
+ ] );
+ # The main two signature forms used above are time-sensitive
+ $this->mOutput->setFlag( 'user-signature' );
+ }
# Context links ("pipe tricks"): [[|name]] and [[name (context)|]]
$tc = '[' . Title::legalChars() . ']';
* @throws MWException
* @return callable|null The old value of the mTagHooks array associated with the hook
*/
- public function setHook( $tag, $callback ) {
+ public function setHook( $tag, callable $callback ) {
$tag = strtolower( $tag );
if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
throw new MWException( "Invalid character {$m[0]} in setHook('$tag', ...) call" );
* @throws MWException
* @return callable|null The old value of the mTagHooks array associated with the hook
*/
- public function setTransparentTagHook( $tag, $callback ) {
+ public function setTransparentTagHook( $tag, callable $callback ) {
$tag = strtolower( $tag );
if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
throw new MWException( "Invalid character {$m[0]} in setTransparentHook('$tag', ...) call" );
* @throws MWException
* @return string|callable The old callback function for this name, if any
*/
- public function setFunctionHook( $id, $callback, $flags = 0 ) {
+ public function setFunctionHook( $id, callable $callback, $flags = 0 ) {
global $wgContLang;
$oldVal = isset( $this->mFunctionHooks[$id] ) ? $this->mFunctionHooks[$id][0] : null;
* @throws MWException
* @return null
*/
- public function setFunctionTagHook( $tag, $callback, $flags ) {
+ public function setFunctionTagHook( $tag, callable $callback, $flags ) {
$tag = strtolower( $tag );
if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
throw new MWException( "Invalid character {$m[0]} in setFunctionTagHook('$tag', ...) call" );
* @return string HTML
*/
public function renderImageGallery( $text, $params ) {
-
$mode = false;
if ( isset( $params['mode'] ) ) {
$mode = $params['mode'];
$ig->setContextTitle( $this->mTitle );
$ig->setShowBytes( false );
+ $ig->setShowDimensions( false );
$ig->setShowFilename( false );
$ig->setParser( $this );
$ig->setHideBadImages();
protected function lock() {
if ( $this->mInParse ) {
throw new MWException( "Parser state cleared while parsing. "
- . "Did you call Parser::parse recursively?" );
+ . "Did you call Parser::parse recursively? Lock is held by: " . $this->mInParse );
}
- $this->mInParse = true;
- $recursiveCheck = new ScopedCallback( function() {
+ // Save the backtrace when locking, so that if some code tries locking again,
+ // we can print the lock owner's backtrace for easier debugging
+ $e = new Exception;
+ $this->mInParse = $e->getTraceAsString();
+
+ $recursiveCheck = new ScopedCallback( function () {
$this->mInParse = false;
} );