From 6bfc746e830980c32c639fe473a07018ee4a7c50 Mon Sep 17 00:00:00 2001 From: Tim Starling Date: Sat, 19 Jan 2008 09:03:45 +0000 Subject: [PATCH] * Eliminated message mode (OT_MSG), using OT_PREPROCESS instead. As proposed on wikitech-l. * Fixed #tag behaviour in preprocess() * Fixed #tag quote stripping regex * Made MessageCache::getMessage() never transform its result, that is now left up to the caller. * A few other minor changes --- includes/CoreParserFunctions.php | 7 +- includes/Defines.php | 4 +- includes/GlobalFunctions.php | 29 +------ includes/MessageCache.php | 18 ++-- includes/Parser.php | 142 +++++++++++++------------------ 5 files changed, 76 insertions(+), 124 deletions(-) diff --git a/includes/CoreParserFunctions.php b/includes/CoreParserFunctions.php index 4a89c19391..670676b6e9 100644 --- a/includes/CoreParserFunctions.php +++ b/includes/CoreParserFunctions.php @@ -245,8 +245,8 @@ class CoreParserFunctions { $name = $frame->expand( $names->item( 0 ), PPFrame::STRIP_COMMENTS ); $values = $xpath->query( 'value', $arg ); $value = trim( $frame->expand( $values->item( 0 ) ) ); - if ( preg_match( '/^(?:"|\')(.*)(?:"|\')$/s', $value, $m ) ) { - $value = $m[1]; + if ( preg_match( '/^(?:["\'](.+)["\']|""|\'\')$/s', $value, $m ) ) { + $value = isset( $m[1] ) ? $m[1] : ''; } $attributes[$name] = $value; } @@ -255,7 +255,8 @@ class CoreParserFunctions { $params = array( 'name' => $tagName, 'inner' => $inner, - 'attributes' => $attributes + 'attributes' => $attributes, + 'close' => "", ); return $parser->extensionSubstitution( $params, $frame ); } diff --git a/includes/Defines.php b/includes/Defines.php index 1be90f9702..2d6aee5fed 100644 --- a/includes/Defines.php +++ b/includes/Defines.php @@ -268,8 +268,8 @@ define( 'MW_SUPPORTS_PARSERFIRSTCALLINIT', 1 ); # Parameter to Parser::startExternalParse(). define( 'OT_HTML', 1 ); define( 'OT_WIKI', 2 ); -define( 'OT_MSG' , 3 ); -define( 'OT_PREPROCESS', 4 ); +define( 'OT_PREPROCESS', 3 ); +define( 'OT_MSG' , 3 ); // b/c alias for OT_PREPROCESS # Flags for Parser::setFunctionHook define( 'SFH_NO_HASH', 1 ); diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index e70bc46082..56408a0f1b 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -427,24 +427,12 @@ function wfMsgWeirdKey ( $key ) { function wfMsgGetKey( $key, $useDB, $forContent = false, $transform = true ) { global $wgParser, $wgContLang, $wgMessageCache, $wgLang; - /* btw, is all that code in wfMsgGetKey() that check - * if the message cache exists of not really necessary, or is - * it just paranoia? - * Vyznev: it's probably not necessary - * I think I wrote it in an attempt to report DB - * connection errors properly - * but eventually we gave up on using the - * message cache for that and just hard-coded the strings - * it may have other uses, it's not mere paranoia - */ - - if ( is_object( $wgMessageCache ) ) - $transstat = $wgMessageCache->getTransform(); - + # If $wgMessageCache isn't initialised yet, try to return something sensible. if( is_object( $wgMessageCache ) ) { - if ( ! $transform ) - $wgMessageCache->disableTransform(); $message = $wgMessageCache->get( $key, $useDB, $forContent ); + if ( $transform ) { + $message = $wgMessageCache->transform( $message ); + } } else { if( $forContent ) { $lang = &$wgContLang; @@ -456,22 +444,13 @@ function wfMsgGetKey( $key, $useDB, $forContent = false, $transform = true ) { # ISSUE: Should we try to handle "message/lang" here too? $key = str_replace( ' ' , '_' , $wgContLang->lcfirst( $key ) ); - wfSuppressWarnings(); if( is_object( $lang ) ) { $message = $lang->getMessage( $key ); } else { $message = false; } - wfRestoreWarnings(); - - if ( $transform && strstr( $message, '{{' ) !== false ) { - $message = $wgParser->transformMsg($message, $wgMessageCache->getParserOptions() ); - } } - if ( is_object( $wgMessageCache ) && ! $transform ) - $wgMessageCache->setTransform( $transstat ); - return $message; } diff --git a/includes/MessageCache.php b/includes/MessageCache.php index d1338855ef..fecaa53160 100644 --- a/includes/MessageCache.php +++ b/includes/MessageCache.php @@ -500,9 +500,6 @@ class MessageCache { if( $message === false ) { return '<' . htmlspecialchars($key) . '>'; } - - # Replace brace tags - $message = $this->transform( $message ); return $message; } @@ -584,12 +581,11 @@ class MessageCache { # Clone it and store it $this->mParser = clone $wgParser; } - if ( !$this->mDisableTransform && $this->mParser ) { + if ( $this->mParser ) { if( strpos( $message, '{{' ) !== false ) { $popts = $this->getParserOptions(); - if ( $interface ) { $popts->setInterfaceMessage(true); } + $popts->setInterfaceMessage( $interface ); $message = $this->mParser->transformMsg( $message, $popts ); - if ( $interface ) { $popts->setInterfaceMessage(false); } } } return $message; @@ -597,10 +593,12 @@ class MessageCache { function disable() { $this->mDisable = true; } function enable() { $this->mDisable = false; } - function disableTransform() { $this->mDisableTransform = true; } - function enableTransform() { $this->mDisableTransform = false; } - function setTransform( $x ) { $this->mDisableTransform = $x; } - function getTransform() { return $this->mDisableTransform; } + + /** @deprecated */ + function disableTransform() {} + function enableTransform() {} + function setTransform( $x ) {} + function getTransform() { return false; } /** * Add a message to the cache diff --git a/includes/Parser.php b/includes/Parser.php index 24016d8c7f..037c93bc5e 100644 --- a/includes/Parser.php +++ b/includes/Parser.php @@ -15,15 +15,17 @@ * (which in turn the browser understands, and can display). * *
- * There are four main entry points into the Parser class:
+ * There are five main entry points into the Parser class:
  * parse()
  *   produces HTML output
  * preSaveTransform().
  *   produces altered wiki markup.
- * transformMsg()
- *   performs brace substitution on MediaWiki messages
  * preprocess()
  *   removes HTML comments and expands templates
+ * cleanSig()
+ *   Cleans a signature before saving it to preferences
+ * extractSections()
+ *   Extracts sections from an article for section editing
  *
  * Globals used:
  *    objects:   $wgLang, $wgContLang
@@ -247,7 +249,6 @@ class Parser
 		$this->ot = array(
 			'html' => $ot == OT_HTML,
 			'wiki' => $ot == OT_WIKI,
-			'msg' => $ot == OT_MSG,
 			'pre' => $ot == OT_PREPROCESS,
 		);
 	}
@@ -256,6 +257,9 @@ class Parser
 	 * Set the context title
 	 */
 	function setTitle( $t ) {
+		if ( !$t || $t instanceof FakeTitle ) {
+			$t = Title::newFromText( 'NO TITLE' );
+		}
 		if ( strval( $t->getFragment() ) !== '' ) {
 			# Strip the fragment to avoid various odd effects
 			$this->mTitle = clone $t;
@@ -453,9 +457,6 @@ class Parser
 		wfRunHooks( 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ) );
 		wfRunHooks( 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState ) );
 		$text = $this->replaceVariables( $text );
-		if ( $this->mOptions->getRemoveComments() ) {
-			$text = Sanitizer::removeHTMLcomments( $text );
-		}
 		$text = $this->mStripState->unstripBoth( $text );
 		wfProfileOut( __METHOD__ );
 		return $text;
@@ -2581,7 +2582,7 @@ class Parser
 	 *          self::PTD_FOR_INCLUSION    Handle / as if the text is being 
 	 *                                     included. Default is to assume a direct page view. 
 	 *
-	 * The generated DOM tree must depend only on the input text, the flags, and $this->ot['msg']. 
+	 * The generated DOM tree must depend only on the input text and the flags.
 	 * The DOM tree must be the same in OT_HTML and OT_WIKI mode, to avoid a regression of bug 4899. 
 	 *
 	 * Any flag added to the $flags parameter here, or any other parameter liable to cause a 
@@ -2598,47 +2599,24 @@ class Parser
 		wfProfileIn( __METHOD__ );
 		wfProfileIn( __METHOD__.'-makexml' );
 
-		static $msgRules, $normalRules, $inclusionSupertags, $nonInclusionSupertags;
-		if ( !$msgRules ) {
-			$msgRules = array(
-				'{' => array(
-					'end' => '}',
-					'names' => array(
-						2 => 'template',
-					),
-					'min' => 2,
-					'max' => 2,
-				),
-				'[' => array(
-					'end' => ']',
-					'names' => array( 2 => null ),
-					'min' => 2,
-					'max' => 2,
-				)
-			);
-			$normalRules = array(
-				'{' => array(
-					'end' => '}',
-					'names' => array(
-						2 => 'template',
-						3 => 'tplarg',
-					),
-					'min' => 2,
-					'max' => 3,
+		$rules = array(
+			'{' => array(
+				'end' => '}',
+				'names' => array(
+					2 => 'template',
+					3 => 'tplarg',
 				),
-				'[' => array(
-					'end' => ']',
-					'names' => array( 2 => null ),
-					'min' => 2,
-					'max' => 2,
-				)
-			);
-		}
-		if ( $this->ot['msg'] ) {
-			$rules = $msgRules;
-		} else {
-			$rules = $normalRules;
-		}
+				'min' => 2,
+				'max' => 3,
+			),
+			'[' => array(
+				'end' => ']',
+				'names' => array( 2 => null ),
+				'min' => 2,
+				'max' => 2,
+			)
+		);
+
 		$forInclusion = $flags & self::PTD_FOR_INCLUSION;
 
 		$xmlishElements = $this->getStripList();
@@ -2662,7 +2640,7 @@ class Parser
 	
 		$stack = new PPDStack;
 
-		$searchBase = implode( '', array_keys( $rules ) ) . '<';
+		$searchBase = '[{<';
 		$revText = strrev( $text ); // For fast reverse searches
 
 		$i = 0;                     # Input pointer, starts out pointing to a pseudo-newline before the start
@@ -2931,8 +2909,14 @@ class Parser
 				if ( preg_match( "/\s*(={{$count}})/A", $revText, $m, 0, strlen( $text ) - $i ) ) {
 					if ( $i - strlen( $m[0] ) == $piece->startPos ) {
 						// This is just a single string of equals signs on its own line
-						// Divide by two and round down to create start and end delimiters
-						$count = intval( $count / 2 );
+						// Replicate the doHeadings behaviour /={count}(.+)={count}/
+						if ( $count < 3 ) {
+							$count = 0;
+						} elseif ( $count % 2 ) {
+							$count = ( $count - 1 ) / 2;
+						} else {
+							$count = $count / 2 - 1;
+						}
 					} else {
 						$count = min( strlen( $m[1] ), $count );
 					}
@@ -3160,8 +3144,8 @@ class Parser
 	 *
 	 * Note that the substitution depends on value of $mOutputType:
 	 *  OT_WIKI: only {{subst:}} templates
-	 *  OT_MSG: only magic variables
-	 *  OT_HTML: all templates and magic variables
+	 *  OT_PREPROCESS: templates but not extension tags
+	 *  OT_HTML: all templates and extension tags
 	 *
 	 * @param string $tex The text to transform
 	 * @param PPFrame $frame Object describing the arguments passed to the template
@@ -3733,6 +3717,15 @@ class Parser
 					}
 			}
 		} else {
+			if ( is_null( $attrText ) ) {
+				$attrText = '';
+			}
+			if ( isset( $params['attributes'] ) ) {
+				foreach ( $params['attributes'] as $attrName => $attrValue ) {
+					$attrText .= ' ' . htmlspecialchars( $attrName ) . '="' .
+						htmlspecialchars( $attrValue ) . '"';
+				}
+			}
 			if ( $content === null ) {
 				$output = "<$name$attrText/>";
 			} else {
@@ -4244,7 +4237,10 @@ class Parser
 	function cleanSig( $text, $parsing = false ) {
 		if ( !$parsing ) {
 			global $wgTitle;
-			$this->startExternalParse( $wgTitle, new ParserOptions(), OT_MSG );
+			$this->clearState();
+			$this->setTitle( $wgTitle );
+			$this->mOptions = new ParserOptions;
+			$this->setOutputType = OT_PREPROCESS;
 		}
 
 		# FIXME: regex doesn't respect extension tags or nowiki
@@ -4291,16 +4287,11 @@ class Parser
 	}
 
 	/**
-	 * Transform a MediaWiki message by replacing magic variables.
-	 *
-	 * For some unknown reason, it also expands templates, but only to the 
-	 * first recursion level. This is wrong and broken, probably introduced 
-	 * accidentally during refactoring, but probably relied upon by thousands 
-	 * of users. 
+	 * Wrapper for preprocess()
 	 *
-	 * @param string $text the text to transform
+	 * @param string $text the text to preprocess
 	 * @param ParserOptions $options  options
-	 * @return string the text with variables substituted
+	 * @return string
 	 * @public
 	 */
 	function transformMsg( $text, $options ) {
@@ -4316,17 +4307,7 @@ class Parser
 		$executing = true;
 
 		wfProfileIn($fname);
-
-		if ( $wgTitle && !( $wgTitle instanceof FakeTitle ) ) {
-			$this->setTitle( $wgTitle );
-		} else {
-			$this->setTitle( Title::newFromText('msg') );
-		}
-		$this->mOptions = $options;
-		$this->setOutputType( OT_MSG );
-		$this->clearState();
-		$text = $this->replaceVariables( $text );
-		$text = $this->mStripState->unstripBoth( $text );
+		$text = $this->preprocess( $text, $wgTitle, $options );
 
 		$executing = false;
 		wfProfileOut($fname);
@@ -5415,18 +5396,12 @@ class PPFrame {
 			return $root;
 		}
 
-		if ( $this->parser->ot['html'] 
-			&& ++$this->parser->mPPNodeCount > $this->parser->mOptions->mMaxPPNodeCount ) 
+		if ( ++$this->parser->mPPNodeCount > $this->parser->mOptions->mMaxPPNodeCount ) 
 		{
-			return $this->parser->insertStripItem( '' );
+			return 'Node-count limit exceeded';
 		}
 
-		if ( is_array( $root ) ) {
-			$s = '';
-			foreach ( $root as $node ) {
-				$s .= $this->expand( $node, $flags );
-			}
-		} elseif ( $root instanceof DOMNodeList ) {
+		if ( is_array( $root ) || $root instanceof DOMNodeList ) {
 			$s = '';
 			foreach ( $root as $node ) {
 				$s .= $this->expand( $node, $flags );
@@ -5457,7 +5432,7 @@ class PPFrame {
 				$titles = $xpath->query( 'title', $root );
 				$title = $titles->item( 0 );
 				$parts = $xpath->query( 'part', $root );
-				if ( $flags & self::NO_ARGS || $this->parser->ot['msg'] ) {
+				if ( $flags & self::NO_ARGS ) {
 					$s = '{{{' . $this->implodeWithFlags( '|', $flags, $title, $parts ) . '}}}';
 				} else {
 					$params = array( 'title' => $title, 'parts' => $parts, 'text' => 'FIXME' );
@@ -5699,7 +5674,6 @@ class PPTemplateFrame extends PPFrame {
 	}
 
 	function getArgument( $name ) {
-		wfDebug( __METHOD__." getting '$name'\n" );
 		$text = $this->getNumberedArgument( $name );
 		if ( $text === false ) {
 			$text = $this->getNamedArgument( $name );
-- 
2.20.1