From: Bartosz DziewoĆski
Date: Mon, 13 Jul 2015 15:31:52 +0000 (+0200)
Subject: Parser: Don't generate an external link on "http://)" and similar
X-Git-Tag: 1.31.0-rc.0~10509^2
X-Git-Url: https://git.cyclocoop.org/%27.WWW_URL.%27admin/?a=commitdiff_plain;h=bd7e02f39f89366fcccd9304b9b63bcb4df58fa4;p=lhc%2Fweb%2Fwiklou.git
Parser: Don't generate an external link on ")" and similar
Bug: T105697
Change-Id: I6cd14b9c4a541af8d0bb50b925aa0b015e97c3fe
---
diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php
index 65d8182151..7dab564356 100644
--- a/includes/parser/Parser.php
+++ b/includes/parser/Parser.php
@@ -1382,16 +1382,18 @@ class Parser {
$spdash = "(?:-|$space)"; # a dash or a non-newline space
$spaces = "$space++"; # possessive match of 1 or more spaces
$text = preg_replace_callback(
- '!(?: # Start cases
- (].*?) | # m[1]: Skip link text
- (<.*?>) | # m[2]: Skip stuff inside HTML elements' . "
- (\b(?i:$prots)$urlChar+) | # m[3]: Free external links
- \b(?:RFC|PMID) $spaces # m[4]: RFC or PMID, capture number
+ '!(?: # Start cases
+ (].*?) | # m[1]: Skip link text
+ (<.*?>) | # m[2]: Skip stuff inside
+ # HTML elements' . "
+ (\b(?i:$prots)($urlChar+)) | # m[3]: Free external links
+ # m[4]: Post-protocol path
+ \b(?:RFC|PMID) $spaces # m[5]: RFC or PMID, capture number
([0-9]+)\b |
- \bISBN $spaces ( # m[5]: ISBN, capture number
- (?: 97[89] $spdash? )? # optional 13-digit ISBN prefix
- (?: [0-9] $spdash? ){9} # 9 digits with opt. delimiters
- [0-9Xx] # check digit
+ \bISBN $spaces ( # m[6]: ISBN, capture number
+ (?: 97[89] $spdash? )? # optional 13-digit ISBN prefix
+ (?: [0-9] $spdash? ){9} # 9 digits with opt. delimiters
+ [0-9Xx] # check digit
)\b
)!xu", array( &$this, 'magicLinkCallback' ), $text );
return $text;
@@ -1411,28 +1413,28 @@ class Parser {
return $m[0];
} elseif ( isset( $m[3] ) && $m[3] !== '' ) {
# Free external link
- return $this->makeFreeExternalLink( $m[0] );
- } elseif ( isset( $m[4] ) && $m[4] !== '' ) {
+ return $this->makeFreeExternalLink( $m[0], strlen( $m[4] ) );
+ } elseif ( isset( $m[5] ) && $m[5] !== '' ) {
# RFC or PMID
if ( substr( $m[0], 0, 3 ) === 'RFC' ) {
$keyword = 'RFC';
$urlmsg = 'rfcurl';
$cssClass = 'mw-magiclink-rfc';
- $id = $m[4];
+ $id = $m[5];
} elseif ( substr( $m[0], 0, 4 ) === 'PMID' ) {
$keyword = 'PMID';
$urlmsg = 'pubmedurl';
$cssClass = 'mw-magiclink-pmid';
- $id = $m[4];
+ $id = $m[5];
} else {
throw new MWException( __METHOD__ . ': unrecognised match type "' .
substr( $m[0], 0, 20 ) . '"' );
}
$url = wfMessage( $urlmsg, $id )->inContentLanguage()->text();
return Linker::makeExternalLink( $url, "{$keyword} {$id}", true, $cssClass );
- } elseif ( isset( $m[5] ) && $m[5] !== '' ) {
+ } elseif ( isset( $m[6] ) && $m[6] !== '' ) {
# ISBN
- $isbn = $m[5];
+ $isbn = $m[6];
$space = self::SPACE_NOT_NL; # non-newline space
$isbn = preg_replace( "/$space/", ' ', $isbn );
$num = strtr( $isbn, array(
@@ -1453,11 +1455,12 @@ class Parser {
* Make a free external link, given a user-supplied URL
*
* @param string $url
- *
+ * @param int $numPostProto
+ * The number of characters after the protocol.
* @return string HTML
* @private
*/
- public function makeFreeExternalLink( $url ) {
+ public function makeFreeExternalLink( $url, $numPostProto ) {
$trail = '';
@@ -1498,6 +1501,12 @@ class Parser {
$url = Sanitizer::cleanUrl( $url );
+ # Verify that we still have a real URL after trail removal, and
+ # not just lone protocol
+ if ( strlen( $trail ) >= $numPostProto ) {
+ return $url . $trail;
+ }
+
# Is this an external image?
$text = $this->maybeMakeExternalImage( $url );
if ( $text === false ) {
diff --git a/tests/parser/parserTests.txt b/tests/parser/parserTests.txt
index 9226d4ce0b..aa6357c721 100644
--- a/tests/parser/parserTests.txt
+++ b/tests/parser/parserTests.txt
@@ -4556,6 +4556,25 @@ http://example.com/url_with_entity<
http://example.com/url_with_entity<
!! end
+!! test
+External links: Lone protocols are never linked (T105697)
+!! wikitext
+http://
+http://;
+(http://)
+bitcoin:
+bitcoin:;
+(bitcoin:)
+!! html
+http://
+http://;
+(http://)
+bitcoin:
+bitcoin:;
+(bitcoin:)
+
+!! end
+
!! test
External links: No preceding word characters allowed (bug 65278)
!! wikitext