From 050a29d575b6f809d0cd46be2b91d3d54a70e08d Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 4 Oct 2007 18:59:50 +0000 Subject: [PATCH] * (bug 11560) Fix broken HTML output from weird link nesting in edit comments. Nested links (as in image caption text) still don't work _right_ but they're less wrong. Linker::formatComment() used a multi-pass run without proper protections, making it possible for a later 'link' to erase a previous pass's start or end tag. Switched to a single-pass run with preg_replace_callback which avoids this. --- RELEASE-NOTES | 3 +++ includes/Linker.php | 55 +++++++++++++++++++++++++-------------------- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 495aa4d8b1..6d395da19c 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -84,6 +84,9 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN * (bug 11478) Fix undefined method call in file deletion interface * (bug 278) Search results no longer highlight incorrect partial word matches * Compatibility with incorrectly detected old-style DJVU mime types +* (bug 11560) Fix broken HTML output from weird link nesting in edit comments. + Nested links (as in image caption text) still don't work _right_ but they're + less wrong. === API changes in 1.12 === diff --git a/includes/Linker.php b/includes/Linker.php index 1d187b8ca9..e61578d51c 100644 --- a/includes/Linker.php +++ b/includes/Linker.php @@ -988,42 +988,49 @@ class Linker { * Formats wiki links and media links in text; all other wiki formatting * is ignored * + * @fixme doesn't handle sub-links as in image thumb texts like the main parser * @param string $comment Text to format links in * @return string */ public function formatLinksInComment( $comment ) { + return preg_replace_callback( + '/\[\[:?(.*?)(\|(.*?))*\]\]([^[]*)/', + array( $this, 'formatLinksInCommentCallback' ), + $comment ); + } + + protected function formatLinksInCommentCallback( $match ) { global $wgContLang; $medians = '(?:' . preg_quote( Namespace::getCanonicalName( NS_MEDIA ), '/' ) . '|'; $medians .= preg_quote( $wgContLang->getNsText( NS_MEDIA ), '/' ) . '):'; + + $comment = $match[0]; - $match = array(); - while(preg_match('/\[\[:?(.*?)(\|(.*?))*\]\](.*)$/',$comment,$match)) { - # Handle link renaming [[foo|text]] will show link as "text" - if( "" != $match[3] ) { - $text = $match[3]; - } else { - $text = $match[1]; - } - $submatch = array(); - if( preg_match( '/^' . $medians . '(.*)$/i', $match[1], $submatch ) ) { - # Media link; trail not supported. - $linkRegexp = '/\[\[(.*?)\]\]/'; - $thelink = $this->makeMediaLink( $submatch[1], "", $text ); + # Handle link renaming [[foo|text]] will show link as "text" + if( "" != $match[3] ) { + $text = $match[3]; + } else { + $text = $match[1]; + } + $submatch = array(); + if( preg_match( '/^' . $medians . '(.*)$/i', $match[1], $submatch ) ) { + # Media link; trail not supported. + $linkRegexp = '/\[\[(.*?)\]\]/'; + $thelink = $this->makeMediaLink( $submatch[1], "", $text ); + } else { + # Other kind of link + if( preg_match( $wgContLang->linkTrail(), $match[4], $submatch ) ) { + $trail = $submatch[1]; } else { - # Other kind of link - if( preg_match( $wgContLang->linkTrail(), $match[4], $submatch ) ) { - $trail = $submatch[1]; - } else { - $trail = ""; - } - $linkRegexp = '/\[\[(.*?)\]\]' . preg_quote( $trail, '/' ) . '/'; - if (isset($match[1][0]) && $match[1][0] == ':') - $match[1] = substr($match[1], 1); - $thelink = $this->makeLink( $match[1], $text, "", $trail ); + $trail = ""; } - $comment = preg_replace( $linkRegexp, StringUtils::escapeRegexReplacement( $thelink ), $comment, 1 ); + $linkRegexp = '/\[\[(.*?)\]\]' . preg_quote( $trail, '/' ) . '/'; + if (isset($match[1][0]) && $match[1][0] == ':') + $match[1] = substr($match[1], 1); + $thelink = $this->makeLink( $match[1], $text, "", $trail ); } + $comment = preg_replace( $linkRegexp, StringUtils::escapeRegexReplacement( $thelink ), $comment, 1 ); return $comment; } -- 2.20.1