Show a warning in edit preview when a template loop is detected
[lhc/web/wiklou.git] / includes / parser / Parser.php
index ecee0e2..c0a648c 100644 (file)
@@ -245,7 +245,7 @@ class Parser {
        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;
@@ -3261,6 +3261,8 @@ class Parser {
                                        . wfMessage( 'parser-template-loop-warning', $titleText )->inContentLanguage()->text()
                                        . '</span>';
                                $this->addTrackingCategory( 'template-loop-category' );
+                               $this->mOutput->addWarning( wfMessage( 'template-loop-warning',
+                                       wfEscapeWikiText( $titleText ) )->text() );
                                wfDebug( __METHOD__ . ": template loop broken at '$titleText'\n" );
                        }
                }
@@ -4400,7 +4402,6 @@ class Parser {
                        $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 ) {
@@ -4975,6 +4976,7 @@ class Parser {
 
                $ig->setContextTitle( $this->mTitle );
                $ig->setShowBytes( false );
+               $ig->setShowDimensions( false );
                $ig->setShowFilename( false );
                $ig->setParser( $this );
                $ig->setHideBadImages();
@@ -6073,9 +6075,13 @@ class Parser {
        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;
+
+               // 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;