Merge "define RC_EXTERNAL type for recent changes"
[lhc/web/wiklou.git] / includes / parser / Preprocessor_DOM.php
index 7fe420d..b2dd7db 100644 (file)
@@ -126,6 +126,7 @@ class Preprocessor_DOM implements Preprocessor {
         * cache may be implemented at a later date which takes further advantage of these strict
         * dependency requirements.
         *
+        * @throws MWException
         * @return PPNode_DOM
         */
        function preprocessToObj( $text, $flags = 0 ) {
@@ -162,6 +163,15 @@ class Preprocessor_DOM implements Preprocessor {
                        }
 
                }
+
+               // Fail if the number of elements exceeds acceptable limits
+               // Do not attempt to generate the DOM
+               $this->parser->mGeneratedPPNodeCount += substr_count( $xml, '<' );
+               $max = $this->parser->mOptions->getMaxGeneratedPPNodeCount();
+               if ( $this->parser->mGeneratedPPNodeCount > $max ) {
+                       throw new MWException( __METHOD__.': generated node count limit exceeded' );
+               }
+
                wfProfileIn( __METHOD__.'-loadXML' );
                $dom = new DOMDocument;
                wfSuppressWarnings();
@@ -235,6 +245,7 @@ class Preprocessor_DOM implements Preprocessor {
 
                $searchBase = "[{<\n"; #}
                $revText = strrev( $text ); // For fast reverse searches
+               $lengthText = strlen( $text );
 
                $i = 0;                     # Input pointer, starts out pointing to a pseudo-newline before the start
                $accum =& $stack->getAccum();   # Current accumulator
@@ -290,7 +301,7 @@ class Preprocessor_DOM implements Preprocessor {
                                        $accum .= htmlspecialchars( substr( $text, $i, $literalLength ) );
                                        $i += $literalLength;
                                }
-                               if ( $i >= strlen( $text ) ) {
+                               if ( $i >= $lengthText ) {
                                        if ( $currentClosing == "\n" ) {
                                                // Do a past-the-end run to finish off the heading
                                                $curChar = '';
@@ -354,10 +365,10 @@ class Preprocessor_DOM implements Preprocessor {
                                                // Unclosed comment in input, runs to end
                                                $inner = substr( $text, $i );
                                                $accum .= '<comment>' . htmlspecialchars( $inner ) . '</comment>';
-                                               $i = strlen( $text );
+                                               $i = $lengthText;
                                        } else {
                                                // Search backwards for leading whitespace
-                                               $wsStart = $i ? ( $i - strspn( $revText, ' ', strlen( $text ) - $i ) ) : 0;
+                                               $wsStart = $i ? ( $i - strspn( $revText, ' ', $lengthText - $i ) ) : 0;
                                                // Search forwards for trailing whitespace
                                                // $wsEnd will be the position of the last space (or the '>' if there's none)
                                                $wsEnd = $endPos + 2 + strspn( $text, ' ', $endPos + 3 );
@@ -438,7 +449,7 @@ class Preprocessor_DOM implements Preprocessor {
                                        } else {
                                                // No end tag -- let it run out to the end of the text.
                                                $inner = substr( $text, $tagEndPos + 1 );
-                                               $i = strlen( $text );
+                                               $i = $lengthText;
                                                $close = '';
                                        }
                                }
@@ -498,16 +509,16 @@ class Preprocessor_DOM implements Preprocessor {
                                $part = $piece->getCurrentPart();
                                // Search back through the input to see if it has a proper close
                                // Do this using the reversed string since the other solutions (end anchor, etc.) are inefficient
-                               $wsLength = strspn( $revText, " \t", strlen( $text ) - $i );
+                               $wsLength = strspn( $revText, " \t", $lengthText - $i );
                                $searchStart = $i - $wsLength;
                                if ( isset( $part->commentEnd ) && $searchStart - 1 == $part->commentEnd ) {
                                        // Comment found at line end
                                        // Search for equals signs before the comment
                                        $searchStart = $part->visualEnd;
-                                       $searchStart -= strspn( $revText, " \t", strlen( $text ) - $searchStart );
+                                       $searchStart -= strspn( $revText, " \t", $lengthText - $searchStart );
                                }
                                $count = $piece->count;
-                               $equalsLength = strspn( $revText, '=', strlen( $text ) - $searchStart );
+                               $equalsLength = strspn( $revText, '=', $lengthText - $searchStart );
                                if ( $equalsLength > 0 ) {
                                        if ( $searchStart - $equalsLength == $piece->startPos ) {
                                                // This is just a single string of equals signs on its own line
@@ -1663,6 +1674,7 @@ class PPNode_DOM implements PPNode {
         *  - index         String index
         *  - value         PPNode value
         *
+        * @throws MWException
         * @return array
         */
        function splitArg() {
@@ -1684,6 +1696,7 @@ class PPNode_DOM implements PPNode {
         * Split an "<ext>" node into an associative array containing name, attr, inner and close
         * All values in the resulting array are PPNodes. Inner and close are optional.
         *
+        * @throws MWException
         * @return array
         */
        function splitExt() {
@@ -1709,6 +1722,7 @@ class PPNode_DOM implements PPNode {
 
        /**
         * Split a "<h>" node
+        * @throws MWException
         * @return array
         */
        function splitHeading() {