Skip to content

Commit

Permalink
Item5969: Add support for IPv6 addresses in sq bracket links.
Browse files Browse the repository at this point in the history
This appears to work fine.  The new dependency on Regexp::IPv6 is
optional. If it's missing, then rendering works how it used to work.

WysiwygPugin needs similar handling.
  • Loading branch information
gac410 committed Mar 29, 2017
1 parent e781ae6 commit 88088d7
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 7 deletions.
87 changes: 85 additions & 2 deletions UnitTestContrib/test/unit/FormattingTests.pm
Expand Up @@ -210,8 +210,12 @@ sub skip {
'FormattingTests::test_shortAcronyms' =>
'Missing Class::Unload',
}
}

},
{
condition => { without_dep => 'Regexp::IPv6' },
tests =>
{ 'FormattingTests::test_IPv6_squab' => 'Missing Regexp::IPv6', }
},
);
}

Expand Down Expand Up @@ -421,6 +425,85 @@ ACTUAL
$Foswiki::cfg{NameFilter} = $saveNameFilter;
}

sub test_IPv6_Inline {
my $this = shift;

# Test examples taken from http://www.faqs.org/rfcs/rfc2732.html

my $expected = <<EXPECTED;
<a href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html</a>
<a href="http://[1080:0:0:0:8:800:200C:417A]/index.html">http://[1080:0:0:0:8:800:200C:417A]/index.html</a>
<a href="http://[3ffe:2a00:100:7031::1]">http://[3ffe:2a00:100:7031::1]</a>
<a href="http://[1080::8:800:200C:417A]/foo">http://[1080::8:800:200C:417A]/foo</a>
<a href="http://[::192.9.5.5]/ipng">http://[::192.9.5.5]/ipng</a>
<a href="http://[::FFFF:129.144.52.38]:80/index.html">http://[::FFFF:129.144.52.38]:80/index.html</a>
<a href="http://[2010:836B:4179::836B:4179]">http://[2010:836B:4179::836B:4179]</a>
<a href="https://metacpan.org/requires/distribution/Moo?sort=%5B[2,1]]&size=500">https://metacpan.org/requires/distribution/Moo?sort=%5B[2,1]]&size=500</a>
EXPECTED

my $actual = <<ACTUAL;
http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html
http://[1080:0:0:0:8:800:200C:417A]/index.html
http://[3ffe:2a00:100:7031::1]
http://[1080::8:800:200C:417A]/foo
http://[::192.9.5.5]/ipng
http://[::FFFF:129.144.52.38]:80/index.html
http://[2010:836B:4179::836B:4179]
https://metacpan.org/requires/distribution/Moo?sort=%5B[2,1]]&size=500
ACTUAL
$this->do_test( $expected, $actual );
}

sub test_IPv6_squab {
my $this = shift;

# Test examples taken from http://www.faqs.org/rfcs/rfc2732.html
#
my $expected = <<EXPECTED;
<a href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html</a>
<a href="http://[1080:0:0:0:8:800:200C:417A]/index.html">http://[1080:0:0:0:8:800:200C:417A]/index.html</a>
<a href="http://[3ffe:2a00:100:7031::1]">http://[3ffe:2a00:100:7031::1]</a>
<a href="http://[1080::8:800:200C:417A]/foo">http://[1080::8:800:200C:417A]/foo</a>
<a href="http://[::192.9.5.5]/ipng">http://[::192.9.5.5]/ipng</a>
<a href="http://[::FFFF:129.144.52.38]:80/index.html">http://[::FFFF:129.144.52.38]:80/index.html</a>
<a href="http://[2010:836B:4179::836B:4179]">http://[2010:836B:4179::836B:4179]</a>
<a href="http://metacpan.org/requires/distribution/Moo?sort=%5b%5b2,1%5d%5d&size=500">http://metacpan.org/requires/distribution/Moo?sort=%5b%5b2,1%5d%5d&size=500</a>
EXPECTED

my $actual = <<ACTUAL;
[[http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html]]
[[http://[1080:0:0:0:8:800:200C:417A]/index.html]]
[[http://[3ffe:2a00:100:7031::1]]]
[[http://[1080::8:800:200C:417A]/foo]]
[[http://[::192.9.5.5]/ipng]]
[[http://[::FFFF:129.144.52.38]:80/index.html]]
[[http://[2010:836B:4179::836B:4179]]]
[[http://metacpan.org/requires/distribution/Moo?sort=%5b%5b2,1%5d%5d&size=500]]
ACTUAL
$this->do_test( $expected, $actual );

$expected = <<EXPECTED;
<a href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">Site 1</a>
<a href="http://[1080:0:0:0:8:800:200C:417A]/index.html">Site 2</a>
<a href="http://[3ffe:2a00:100:7031::1]">Site 3</a>
<a href="http://[1080::8:800:200C:417A]/foo">Site 4</a>
<a href="http://[::192.9.5.5]/ipng">Site 5</a>
<a href="http://[::FFFF:129.144.52.38]:80/index.html">Site 6</a>
<a href="http://[2010:836B:4179::836B:4179]">Site 7</a>
EXPECTED

$actual = <<ACTUAL;
[[http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html][Site 1]]
[[http://[1080:0:0:0:8:800:200C:417A]/index.html][Site 2]]
[[http://[3ffe:2a00:100:7031::1]][Site 3]]
[[http://[1080::8:800:200C:417A]/foo][Site 4]]
[[http://[::192.9.5.5]/ipng][Site 5]]
[[http://[::FFFF:129.144.52.38]:80/index.html][Site 6]]
[[http://[2010:836B:4179::836B:4179]][Site 7]]
ACTUAL
$this->do_test( $expected, $actual );
}

# [[WikiWord]]
sub test_squabbedWikiword {
my $this = shift;
Expand Down
6 changes: 4 additions & 2 deletions core/data/System/EditingShorthand.txt
@@ -1,4 +1,4 @@
%META:TOPICINFO{author="ProjectContributor" date="1473352704" format="1.1" version="1"}%
%META:TOPICINFO{author="ProjectContributor" date="1490749805" format="1.1" version="1"}%
---+ Editing Shorthand
%STARTINCLUDE%
%TABLE{}%
Expand Down Expand Up @@ -395,7 +395,9 @@ ACRONYM
%BR%
Text within the brackets may contain optional spaces; the topic name is formed by capitalizing the initial letter and by removing the spaces; for example, =[<nop>[wiki word]]= links to topic WikiWord. You can also refer to a different web and use anchors.
%BR%
%T% To "escape" double square brackets that would otherwise make a link, prefix the leading left square bracket with an exclamation point.
%T% To "escape" double square brackets that would otherwise make a link, prefix the leading left square bracket with an exclamation point.
%BR%
%T% To use a square bracket inside another URL, they need to be URL encoded. Replace [ with =%5B= and ] with =%5D=.
</td><td>
<pre class="tml">
[[wiki syntax]]
Expand Down
1 change: 1 addition & 0 deletions core/lib/Foswiki/Contrib/core/DEPENDENCIES
Expand Up @@ -31,6 +31,7 @@ Locale::Msgfmt,>=0,cpan,Optional, used to compress the language files in locale
LWP,>=0,cpan,Required, needed by the Configure Extensions installer,for external URL based INCLUDEs and URL item verification.
LWP::Protocol::https,>=0,cpan,Required, needed by the Configure Extensions installer,for external URL based INCLUDEs and URL item verification.
Mozilla::CA,>=20110904,cpan,Optional, SSL host verification for e-mail and other SSL/TLS connections.
Regexp::IPv6,>=0,cpan,Optional, required to use IPv6 addresses inside square bracket links.
Socket,>=2.001,cpan,Required, for base Foswiki.
URI,>=0,cpan,Required, used for Foswiki::Net URL parsing
version,>=0.77,cpan,Required, Used for standard perl version strings.
Expand Down
33 changes: 30 additions & 3 deletions core/lib/Foswiki/Render.pm
Expand Up @@ -524,10 +524,36 @@ qr/<[Tt][Ee][Xx][Tt][Aa][Rr][Ee][Aa]\b.*?<\/[Tt][Ee][Xx][Tt][Aa][Rr][Ee][Aa]>/s,
# Change ' ![[...' to ' [<nop>[...' to protect from further rendering
$text =~ s/(^|\s)\!\[\[/$1\[<nop>\[/gm;

my $remove_v6 = {};
if ( eval 'require Regexp::IPv6' ) {

# Remove IPv6 addresses, as they break square bracket links.
$text =
$this->_takeOutProtected( $text, qr/\[$Regexp::IPv6::IPv6_re\]/s,
'ipv6', $remove_v6 );
}

# Spaced-out Wiki words with alternative link text
# i.e. [[$1][$3]]
$text =~ s(\[\[([^\]\[\n]+)\](\[([^\]\n]+)\])?\])
(_handleSquareBracketedLink( $this,$topicObject,$1,$3))ge;
$text =~ s(
\[\[
(
[^\]\[\n]+ # The link
)
\]
(?:
\[
(
[^\]\n]+ # Optional link text
)
\]
)?
\]
)
(_handleSquareBracketedLink( $this,$topicObject,$1,$2))gex;

$this->_putBackProtected( \$text, 'ipv6', $remove_v6 )
if ( scalar $remove_v6 );

# URI - don't apply if the URI is surrounded by url() to avoid naffing
# CSS
Expand Down Expand Up @@ -1798,7 +1824,8 @@ sub _putBackProtected {
# Reset position for next pass
$pos = 0;

delete( $map->{$placeholder} );
#SMELL: Can't do this, [[links]] might duplicate placeholders
#delete( $map->{$placeholder} );
}

$ntext .= $otext; # Append any remaining text.
Expand Down

0 comments on commit 88088d7

Please sign in to comment.