X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Fparser%2FPreprocessor_DOM.php;h=5da7cd7441c62e4d74b0f9a47cb1deaebb38deac;hp=4c94b2ae90d3e568122989036f0b4b7a89fb8b56;hb=ce079cf6ad79ca8d3360817f809b219d166f9153;hpb=61846a5ab06afc81ef213be3357a884d7f72b45a diff --git a/includes/parser/Preprocessor_DOM.php b/includes/parser/Preprocessor_DOM.php index 4c94b2ae90..5da7cd7441 100644 --- a/includes/parser/Preprocessor_DOM.php +++ b/includes/parser/Preprocessor_DOM.php @@ -196,6 +196,7 @@ class Preprocessor_DOM extends Preprocessor { $forInclusion = $flags & Parser::PTD_FOR_INCLUSION; $xmlishElements = $this->parser->getStripList(); + $xmlishAllowMissingEndTag = [ 'includeonly', 'noinclude', 'onlyinclude' ]; $enableOnlyinclude = false; if ( $forInclusion ) { $ignoredTags = [ 'includeonly', '/includeonly' ]; @@ -237,6 +238,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 = []; // True to ignore all input up to the next $findOnlyinclude = $enableOnlyinclude; // Do a line-start run without outputting an LF character @@ -457,17 +460,29 @@ 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 + if ( in_array( $name, $xmlishAllowMissingEndTag ) ) { + // Let it run out to the end of the text. + $inner = substr( $text, $tagEndPos + 1 ); + $i = $lengthText; + $close = ''; + } else { + // 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 @@ -524,7 +539,7 @@ class Preprocessor_DOM extends Preprocessor { } elseif ( $found == 'line-end' ) { $piece = $stack->top; // A heading must be open, otherwise \n wouldn't have been in the search list - assert( '$piece->open == "\n"' ); + assert( $piece->open === "\n" ); $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