Merge changes Ic19071c7,Icc8dc4ae
authorAaron Schulz <aschulz@wikimedia.org>
Tue, 8 May 2012 22:54:59 +0000 (22:54 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 8 May 2012 22:54:59 +0000 (22:54 +0000)
* changes:
  Message documentation for Icc8dc4ae (circular references in strip tags)
  (bug 35315) Detect circular references in strip tags

includes/parser/StripState.php
languages/messages/MessagesEn.php
languages/messages/MessagesQqq.php

index 321fcd8..b08aa14 100644 (file)
@@ -31,6 +31,10 @@ class StripState {
        protected $regex;
 
        protected $tempType, $tempMergePrefix;
+       protected $circularRefGuard;
+       protected $recursionLevel = 0;
+
+       const UNSTRIP_RECURSION_LIMIT = 20;
 
        /**
         * @param $prefix string
@@ -42,6 +46,7 @@ class StripState {
                        'general' => array()
                );
                $this->regex = "/{$this->prefix}([^\x7f]+)" . Parser::MARKER_SUFFIX . '/';
+               $this->circularRefGuard = array();
        }
 
        /**
@@ -113,12 +118,10 @@ class StripState {
                }
 
                wfProfileIn( __METHOD__ );
+               $oldType = $this->tempType;
                $this->tempType = $type;
-               do {
-                       $oldText = $text;
-                       $text = preg_replace_callback( $this->regex, array( $this, 'unstripCallback' ), $text );
-               } while ( $text !== $oldText );
-               $this->tempType = null;
+               $text = preg_replace_callback( $this->regex, array( $this, 'unstripCallback' ), $text );
+               $this->tempType = $oldType;
                wfProfileOut( __METHOD__ );
                return $text;
        }
@@ -128,8 +131,22 @@ class StripState {
         * @return array
         */
        protected function unstripCallback( $m ) {
-               if ( isset( $this->data[$this->tempType][$m[1]] ) ) {
-                       return $this->data[$this->tempType][$m[1]];
+               $marker = $m[1];
+               if ( isset( $this->data[$this->tempType][$marker] ) ) {
+                       if ( isset( $this->circularRefGuard[$marker] ) ) {
+                               return '<span class="error">' . wfMsgForContent( 'parser-unstrip-loop-warning' ) . '</span>';
+                       }
+                       if ( $this->recursionLevel >= self::UNSTRIP_RECURSION_LIMIT ) {
+                               return '<span class="error">' . 
+                                       wfMsgForContent( 'parser-unstrip-recursion-limit', self::UNSTRIP_RECURSION_LIMIT ) . 
+                                       '</span>';
+                       }
+                       $this->circularRefGuard[$marker] = true;
+                       $this->recursionLevel++;
+                       $ret = $this->unstripType( $this->tempType, $this->data[$this->tempType][$marker] );
+                       $this->recursionLevel--;
+                       unset( $this->circularRefGuard[$marker] );
+                       return $ret;
                } else {
                        return $m[0];
                }
index c3af5bf..bb405b6 100644 (file)
@@ -1484,6 +1484,8 @@ These arguments have been omitted.",
 'node-count-exceeded-warning'             => 'Page exceeded the node-count',
 'expansion-depth-exceeded-category'       => 'Pages where expansion depth is exceeded',
 'expansion-depth-exceeded-warning'        => 'Page exceeded the expansion depth',
+'parser-unstrip-loop-warning'             => 'Unstrip loop detected',
+'parser-unstrip-recursion-limit'          => 'Unstrip recursion limit exceeded ($1)',
 
 # "Undo" feature
 'undo-success' => 'The edit can be undone.
index 757490e..7a0383c 100644 (file)
@@ -1040,6 +1040,13 @@ When templates are expanded, there is a size limit for the number of bytes yield
 
 * <tt>$1</tt> is the value of the depth limit
 * <tt>$2</tt> is the value of the max depth limit',
+'parser-unstrip-loop-warning' => 'This error is shown when a parser extension tag such as <pre> includes a reference to itself in its own output.
+The reference must be to the exact same invocation of the tag at the same location in the source, merely writing &lt;pre>&lt;pre>&lt;/pre>&lt;/pre> will not do it.
+This is usually impossible and unlikely to happen by accident, so translation is not essential.',
+'parser-unstrip-recursion-limit' => 'This message is shown when the recursion limit for nested parser extension tags is exceeded.
+This warning may be encountered due to input text like &lt;ref>&lt;ref>&lt;ref>...&lt;/ref>&lt;/ref>&lt;/ref>.
+
+* <tt>$1</tt> is the depth limit',
 
 # "Undo" feature
 'undo-success' => 'Text on special page to confirm edit revert. You arrive on this page by clicking on the "undo" link on a revision history special page.