X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fparser%2FPreprocessor_DOM.php;h=817f1538e3672090bdc3eb5063a8b628a37c6c9f;hb=fd8e761b19cb0ff6a01e4e43f00e1f2bb6b28afd;hp=b71b9d242fd6e7dbd840f990758bb455db70b844;hpb=5ad8f11baf52c1dbfbc19371647be775e0db6e74;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/parser/Preprocessor_DOM.php b/includes/parser/Preprocessor_DOM.php index b71b9d242f..817f1538e3 100644 --- a/includes/parser/Preprocessor_DOM.php +++ b/includes/parser/Preprocessor_DOM.php @@ -193,24 +193,6 @@ class Preprocessor_DOM extends Preprocessor { * @return string */ public function preprocessToXml( $text, $flags = 0 ) { - $rules = array( - '{' => array( - 'end' => '}', - 'names' => array( - 2 => 'template', - 3 => 'tplarg', - ), - 'min' => 2, - 'max' => 3, - ), - '[' => array( - 'end' => ']', - 'names' => array( 2 => null ), - 'min' => 2, - 'max' => 2, - ) - ); - $forInclusion = $flags & Parser::PTD_FOR_INCLUSION; $xmlishElements = $this->parser->getStripList(); @@ -255,6 +237,8 @@ class Preprocessor_DOM extends Preprocessor { $inHeading = false; // True if there are no more greater-than (>) signs right of $i $noMoreGT = false; + // Map of tag name => true if there are no more closing tags of given type right of $i + $noMoreClosingTag = array(); // True to ignore all input up to the next $findOnlyinclude = $enableOnlyinclude; // Do a line-start run without outputting an LF character @@ -328,9 +312,9 @@ class Preprocessor_DOM extends Preprocessor { } } elseif ( $curChar == $currentClosing ) { $found = 'close'; - } elseif ( isset( $rules[$curChar] ) ) { + } elseif ( isset( $this->rules[$curChar] ) ) { $found = 'open'; - $rule = $rules[$curChar]; + $rule = $this->rules[$curChar]; } else { # Some versions of PHP have a strcspn which stops on null characters # Ignore and continue @@ -475,17 +459,21 @@ class Preprocessor_DOM extends Preprocessor { } else { $attrEnd = $tagEndPos; // Find closing tag - if ( preg_match( "/<\/" . preg_quote( $name, '/' ) . "\s*>/i", + if ( + !isset( $noMoreClosingTag[$name] ) && + preg_match( "/<\/" . preg_quote( $name, '/' ) . "\s*>/i", $text, $matches, PREG_OFFSET_CAPTURE, $tagEndPos + 1 ) ) { $inner = substr( $text, $tagEndPos + 1, $matches[0][1] - $tagEndPos - 1 ); $i = $matches[0][1] + strlen( $matches[0][0] ); $close = '' . htmlspecialchars( $matches[0][0] ) . ''; } else { - // No end tag -- let it run out to the end of the text. - $inner = substr( $text, $tagEndPos + 1 ); - $i = $lengthText; - $close = ''; + // No end tag -- don't match the tag, treat opening tag as literal and resume parsing. + $i = $tagEndPos + 1; + $accum .= htmlspecialchars( substr( $text, $tagStartPos, $tagEndPos + 1 - $tagStartPos ) ); + // Cache results, otherwise we have O(N^2) performance for input like ... + $noMoreClosingTag[$name] = true; + continue; } } // and just become tags @@ -627,7 +615,7 @@ class Preprocessor_DOM extends Preprocessor { # check for maximum matching characters (if there are 5 closing # characters, we will probably need only 3 - depending on the rules) - $rule = $rules[$piece->open]; + $rule = $this->rules[$piece->open]; if ( $count > $rule['max'] ) { # The specified maximum exists in the callback array, unless the caller # has made an error @@ -696,7 +684,7 @@ class Preprocessor_DOM extends Preprocessor { $piece->parts = array( new PPDPart ); $piece->count -= $matchingCount; # do we still qualify for any callback with remaining count? - $min = $rules[$piece->open]['min']; + $min = $this->rules[$piece->open]['min']; if ( $piece->count >= $min ) { $stack->push( $piece ); $accum =& $stack->getAccum();