From eb6ceb963ea7b32ef852b53d3da3a7e795291359 Mon Sep 17 00:00:00 2001
From: JoshyPHP <s9e.dev@gmail.com>
Date: Sat, 5 Dec 2015 07:55:52 +0100
Subject: [PATCH 01/10] [ticket/14323] Added support for truncating long URLs

PHPBB3-14323
---
 phpBB/phpbb/textformatter/s9e/factory.php     | 28 ++++++++++++-
 phpBB/phpbb/textformatter/s9e/parser.php      | 40 +++++++++++++++++++
 .../s9e/default_formatting_test.php           | 10 +++++
 3 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php
index 63b23d2fd0..dd3102d4de 100644
--- a/phpBB/phpbb/textformatter/s9e/factory.php
+++ b/phpBB/phpbb/textformatter/s9e/factory.php
@@ -332,8 +332,7 @@ class factory implements \phpbb\textformatter\cache_interface
 		}
 
 		// Load the magic links plugins. We do that after BBCodes so that they use the same tags
-		$configurator->plugins->load('Autoemail');
-		$configurator->plugins->load('Autolink', array('matchWww' => true));
+		$this->configure_autolink($configurator);
 
 		// Register some vars with a default value. Those should be set at runtime by whatever calls
 		// the parser
@@ -394,6 +393,31 @@ class factory implements \phpbb\textformatter\cache_interface
 		return array('parser' => $parser, 'renderer' => $renderer);
 	}
 
+	/**
+	* Configure the Autolink / Autoemail plugins used to linkify text
+	*
+	* @param  \s9e\TextFormatter\Configurator $configurator
+	* @return void
+	*/
+	protected function configure_autolink(Configurator $configurator)
+	{
+		$configurator->plugins->load('Autoemail');
+		$configurator->plugins->load('Autolink', array('matchWww' => true));
+
+		// Create a tag that will be used to display the truncated text by replacing the original
+		// content with the content of the @text attribute
+		$tag = $configurator->tags->add('AUTOLINK_TEXT');
+		$tag->attributes->add('text');
+		$tag->template = '<xsl:value-of select="@text"/>';
+
+		// Add a tag filter that replaces the text of links that were created by the Autolink plugin
+		$configurator->Autolink->getTag()->filterChain
+			->add(__NAMESPACE__ . '\\parser::generate_autolink_text')
+			->resetParameters()
+			->addParameterByName('tag')
+			->addParameterByName('parser');
+	}
+
 	/**
 	* Return the default BBCodes configuration
 	*
diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php
index ffaffbc63c..faddc806cd 100644
--- a/phpBB/phpbb/textformatter/s9e/parser.php
+++ b/phpBB/phpbb/textformatter/s9e/parser.php
@@ -393,4 +393,44 @@ class parser implements \phpbb\textformatter\parser_interface
 
 		return $url;
 	}
+
+	/**
+	* Replace the content displayed inside of a URL tag
+	*
+	* Will only apply to URL tags that do not use any markup (e.g. not "[url]") on the assumption
+	* that those tags were created by the Autolink plugin to linkify URLs found in plain text
+	*
+	* @param  \s9e\TextFormatter\Parser\Tag $url_tag URL tag (start tag)
+	* @param  \s9e\TextFormatter\Parser     $parser  Parser
+	* @return bool                                   Always TRUE to indicate that the tag is valid
+	*/
+	public static function generate_autolink_text(\s9e\TextFormatter\Parser\Tag $url_tag, \s9e\TextFormatter\Parser $parser)
+	{
+		// If the tag consumes any text then we ignore it because it's not a linkified URL. Same if
+		// it's not paired with an end tag that doesn't consume any text either
+		if ($url_tag->getLen() > 0 || !$url_tag->getEndTag())
+		{
+			return true;
+		}
+
+		// Capture the text between the start tag and its end tag
+		$start  = $url_tag->getPos();
+		$end    = $url_tag->getEndTag()->getPos();
+		$length = $end - $start;
+		$text   = substr($parser->getText(), $start, $length);
+
+		if ($length <= 55 || utf8_strlen($text) <= 55)
+		{
+			// Do not do anything if the text is not longer than 55 characters
+			return true;
+		}
+
+		$tag = $parser->addSelfClosingTag('AUTOLINK_TEXT', $start, $length);
+		$url_tag->cascadeInvalidationTo($tag);
+
+		$text = utf8_substr($text, 0, 39) . ' ... ' . utf8_substr($text, -10);
+		$tag->setAttribute('text', $text);
+
+		return true;
+	}
 }
diff --git a/tests/text_formatter/s9e/default_formatting_test.php b/tests/text_formatter/s9e/default_formatting_test.php
index 3047653d51..facffd5df1 100644
--- a/tests/text_formatter/s9e/default_formatting_test.php
+++ b/tests/text_formatter/s9e/default_formatting_test.php
@@ -225,6 +225,16 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case
 				'... www.example.org ...',
 				'... <a href="http://www.example.org" class="postlink">www.example.org</a> ...'
 			),
+			array(
+				// From make_clickable_test.php
+				'www.phpbb.com/community/?',
+				'<a href="http://www.phpbb.com/community/" class="postlink">www.phpbb.com/community/</a>?'
+			),
+			array(
+				// From make_clickable_test.php
+				'http://www.phpbb.com/community/path/to/long/url/file.ext#section',
+				'<a href="http://www.phpbb.com/community/path/to/long/url/file.ext#section" class="postlink">http://www.phpbb.com/community/path/to/ ... xt#section</a>'
+			),
 			array(
 				'[quote="[url=http://example.org]xxx[/url]"]...[/quote]',
 				'<blockquote><div><cite><a href="http://example.org" class="postlink">xxx</a> wrote:</cite>...</div></blockquote>'

From 8fe94a19b46c4e33a117c1a040415f2b1c397e7c Mon Sep 17 00:00:00 2001
From: JoshyPHP <s9e.dev@gmail.com>
Date: Sat, 5 Dec 2015 19:48:01 +0100
Subject: [PATCH 02/10] [ticket/14323] Added support for truncating local URLs

PHPBB3-14323
---
 phpBB/phpbb/textformatter/s9e/factory.php     |  3 ++-
 phpBB/phpbb/textformatter/s9e/parser.php      | 25 +++++++++++--------
 .../phpbb_test_case_helpers.php               |  9 ++++++-
 .../s9e/default_formatting_test.php           |  8 ++++++
 .../tickets_data/PHPBB3-10587.html            |  4 +--
 .../tickets_data/PHPBB3-10587.txt             |  4 +--
 6 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php
index dd3102d4de..63e49b6dd4 100644
--- a/phpBB/phpbb/textformatter/s9e/factory.php
+++ b/phpBB/phpbb/textformatter/s9e/factory.php
@@ -415,7 +415,8 @@ class factory implements \phpbb\textformatter\cache_interface
 			->add(__NAMESPACE__ . '\\parser::generate_autolink_text')
 			->resetParameters()
 			->addParameterByName('tag')
-			->addParameterByName('parser');
+			->addParameterByName('parser')
+			->addParameterByValue(generate_board_url() . '/');
 	}
 
 	/**
diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php
index faddc806cd..d8a2b8d62c 100644
--- a/phpBB/phpbb/textformatter/s9e/parser.php
+++ b/phpBB/phpbb/textformatter/s9e/parser.php
@@ -400,11 +400,12 @@ class parser implements \phpbb\textformatter\parser_interface
 	* Will only apply to URL tags that do not use any markup (e.g. not "[url]") on the assumption
 	* that those tags were created by the Autolink plugin to linkify URLs found in plain text
 	*
-	* @param  \s9e\TextFormatter\Parser\Tag $url_tag URL tag (start tag)
-	* @param  \s9e\TextFormatter\Parser     $parser  Parser
-	* @return bool                                   Always TRUE to indicate that the tag is valid
+	* @param  \s9e\TextFormatter\Parser\Tag $url_tag   URL tag (start tag)
+	* @param  \s9e\TextFormatter\Parser     $parser    Parser
+	* @param  string                        $board_url Forum's root URL (with trailing slash)
+	* @return bool                                     Always TRUE to indicate that the tag is valid
 	*/
-	public static function generate_autolink_text(\s9e\TextFormatter\Parser\Tag $url_tag, \s9e\TextFormatter\Parser $parser)
+	public static function generate_autolink_text(\s9e\TextFormatter\Parser\Tag $url_tag, \s9e\TextFormatter\Parser $parser, $board_url)
 	{
 		// If the tag consumes any text then we ignore it because it's not a linkified URL. Same if
 		// it's not paired with an end tag that doesn't consume any text either
@@ -419,16 +420,20 @@ class parser implements \phpbb\textformatter\parser_interface
 		$length = $end - $start;
 		$text   = substr($parser->getText(), $start, $length);
 
-		if ($length <= 55 || utf8_strlen($text) <= 55)
+		// Remove the board's root URL from the link if applicable
+		if (stripos($text, $board_url) === 0 && strlen($text) > strlen($board_url))
 		{
-			// Do not do anything if the text is not longer than 55 characters
-			return true;
+			$text = substr($text, strlen($board_url));
 		}
 
-		$tag = $parser->addSelfClosingTag('AUTOLINK_TEXT', $start, $length);
-		$url_tag->cascadeInvalidationTo($tag);
+		// Truncate the text if it's longer than 55 characters
+		if (utf8_strlen($text) > 55)
+		{
+			$text = utf8_substr($text, 0, 39) . ' ... ' . utf8_substr($text, -10);
+		}
 
-		$text = utf8_substr($text, 0, 39) . ' ... ' . utf8_substr($text, -10);
+		// Create a tag that consumes the link's text
+		$tag = $parser->addSelfClosingTag('AUTOLINK_TEXT', $start, $length);
 		$tag->setAttribute('text', $text);
 
 		return true;
diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php
index 0166b11d06..cb77c6829c 100644
--- a/tests/test_framework/phpbb_test_case_helpers.php
+++ b/tests/test_framework/phpbb_test_case_helpers.php
@@ -315,7 +315,7 @@ class phpbb_test_case_helpers
 	public function set_s9e_services(ContainerInterface $container = null, $fixture = null, $styles_path = null)
 	{
 		static $first_run;
-		global $phpbb_container, $phpbb_dispatcher, $phpbb_root_path, $phpEx, $user;
+		global $phpbb_container, $phpbb_dispatcher, $phpbb_root_path, $phpEx, $request, $user;
 
 		$cache_dir = __DIR__ . '/../tmp/';
 
@@ -490,6 +490,12 @@ class phpbb_test_case_helpers
 			}
 		}
 
+		// Create a fake request
+		if (!isset($request))
+		{
+			$request = new phpbb_mock_request;
+		}
+
 		// Create and register the text_formatter.s9e.factory service
 		$factory = new \phpbb\textformatter\s9e\factory($dal, $cache, $dispatcher, $config, $cache_dir, $cache_key_parser, $cache_key_renderer);
 		$container->set('text_formatter.s9e.factory', $factory);
@@ -513,6 +519,7 @@ class phpbb_test_case_helpers
 			     ->will($this->test_case->returnCallback(__CLASS__ . '::format_date'));
 
 			$user->date_format = 'Y-m-d H:i:s';
+			$user->host = 'localhost';
 			$user->optionset('viewcensors', true);
 			$user->optionset('viewflash', true);
 			$user->optionset('viewimg', true);
diff --git a/tests/text_formatter/s9e/default_formatting_test.php b/tests/text_formatter/s9e/default_formatting_test.php
index facffd5df1..b5777a42d4 100644
--- a/tests/text_formatter/s9e/default_formatting_test.php
+++ b/tests/text_formatter/s9e/default_formatting_test.php
@@ -235,6 +235,14 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case
 				'http://www.phpbb.com/community/path/to/long/url/file.ext#section',
 				'<a href="http://www.phpbb.com/community/path/to/long/url/file.ext#section" class="postlink">http://www.phpbb.com/community/path/to/ ... xt#section</a>'
 			),
+			array(
+				'http://localhost/ http://localhost/viewforum.php?f=1',
+				'<a href="http://localhost/" class="postlink">http://localhost/</a> <a href="http://localhost/viewforum.php?f=1" class="postlink">viewforum.php?f=1</a>'
+			),
+			array(
+				'http://localhost/viewforum.php?f=1#xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
+				'<a href="http://localhost/viewforum.php?f=1#xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" class="postlink">viewforum.php?f=1#xxxxxxxxxxxxxxxxxxxxx ... xxxxxxxxxx</a>'
+			),
 			array(
 				'[quote="[url=http://example.org]xxx[/url]"]...[/quote]',
 				'<blockquote><div><cite><a href="http://example.org" class="postlink">xxx</a> wrote:</cite>...</div></blockquote>'
diff --git a/tests/text_processing/tickets_data/PHPBB3-10587.html b/tests/text_processing/tickets_data/PHPBB3-10587.html
index dd0a483244..4c2e536989 100644
--- a/tests/text_processing/tickets_data/PHPBB3-10587.html
+++ b/tests/text_processing/tickets_data/PHPBB3-10587.html
@@ -1,2 +1,2 @@
-<a href="http://www.tx-gaming.net/warzone/tournament.php?tourney%5Bid%5D=34&amp;action=brackets" class="postlink">http://www.tx-gaming.net/warzone/tournament.php?tourney[id]=34&amp;action=brackets</a><br>
-<a href="http://www.tx-gaming.net/warzone/tournament.php?tourney%5Bid%5D=34&amp;action=brackets" class="postlink">link</a>
\ No newline at end of file
+<a href="http://example.org/?tourney%5Bid%5D=34&amp;action=brackets" class="postlink">http://example.org/?tourney[id]=34&amp;action=brackets</a><br>
+<a href="http://example.org/?tourney%5Bid%5D=34&amp;action=brackets" class="postlink">link</a>
\ No newline at end of file
diff --git a/tests/text_processing/tickets_data/PHPBB3-10587.txt b/tests/text_processing/tickets_data/PHPBB3-10587.txt
index f81a35eb5f..84788b720d 100644
--- a/tests/text_processing/tickets_data/PHPBB3-10587.txt
+++ b/tests/text_processing/tickets_data/PHPBB3-10587.txt
@@ -1,2 +1,2 @@
-[url]http://www.tx-gaming.net/warzone/tournament.php?tourney[id]=34&action=brackets[/url]
-[url="http://www.tx-gaming.net/warzone/tournament.php?tourney[id]=34&action=brackets"]link[/url]
\ No newline at end of file
+[url]http://example.org/?tourney[id]=34&action=brackets[/url]
+[url="http://example.org/?tourney[id]=34&action=brackets"]link[/url]
\ No newline at end of file

From 9a8fb2e1df0d63f46ee0a6e4b64dc8530b8db809 Mon Sep 17 00:00:00 2001
From: JoshyPHP <s9e.dev@gmail.com>
Date: Sun, 6 Dec 2015 15:11:26 +0100
Subject: [PATCH 03/10] [ticket/14323] Stylistic change [ci skip]

PHPBB3-14323
---
 phpBB/phpbb/textformatter/s9e/parser.php | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php
index d8a2b8d62c..beb737c816 100644
--- a/phpBB/phpbb/textformatter/s9e/parser.php
+++ b/phpBB/phpbb/textformatter/s9e/parser.php
@@ -397,18 +397,20 @@ class parser implements \phpbb\textformatter\parser_interface
 	/**
 	* Replace the content displayed inside of a URL tag
 	*
-	* Will only apply to URL tags that do not use any markup (e.g. not "[url]") on the assumption
-	* that those tags were created by the Autolink plugin to linkify URLs found in plain text
+	* Will only apply to URL tags that do not use any markup (e.g. not "[url]")
+	* on the assumption that those tags were created by the Autolink plugin to
+	* linkify URLs found in plain text
 	*
 	* @param  \s9e\TextFormatter\Parser\Tag $url_tag   URL tag (start tag)
 	* @param  \s9e\TextFormatter\Parser     $parser    Parser
 	* @param  string                        $board_url Forum's root URL (with trailing slash)
-	* @return bool                                     Always TRUE to indicate that the tag is valid
+	* @return bool                                     Always true to indicate that the tag is valid
 	*/
 	public static function generate_autolink_text(\s9e\TextFormatter\Parser\Tag $url_tag, \s9e\TextFormatter\Parser $parser, $board_url)
 	{
-		// If the tag consumes any text then we ignore it because it's not a linkified URL. Same if
-		// it's not paired with an end tag that doesn't consume any text either
+		// If the tag consumes any text then we ignore it because it's not a
+		// linkified URL. Same if it's not paired with an end tag that doesn't
+		// consume any text either
 		if ($url_tag->getLen() > 0 || !$url_tag->getEndTag())
 		{
 			return true;

From f9d8866aee9bca746801ef0360a5ab350d04061d Mon Sep 17 00:00:00 2001
From: JoshyPHP <s9e.dev@gmail.com>
Date: Sun, 6 Dec 2015 15:23:27 +0100
Subject: [PATCH 04/10] [ticket/14323] Set up global objects required during
 testing

PHPBB3-14323
---
 .../phpbb_test_case_helpers.php               | 26 ++++++++++++-------
 .../s9e/default_formatting_test.php           |  8 +++---
 tests/text_formatter/s9e/factory_test.php     | 16 +++++++++---
 3 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php
index cb77c6829c..aa58b3974b 100644
--- a/tests/test_framework/phpbb_test_case_helpers.php
+++ b/tests/test_framework/phpbb_test_case_helpers.php
@@ -315,7 +315,7 @@ class phpbb_test_case_helpers
 	public function set_s9e_services(ContainerInterface $container = null, $fixture = null, $styles_path = null)
 	{
 		static $first_run;
-		global $phpbb_container, $phpbb_dispatcher, $phpbb_root_path, $phpEx, $request, $user;
+		global $config, $phpbb_container, $phpbb_dispatcher, $phpbb_root_path, $phpEx, $request, $user;
 
 		$cache_dir = __DIR__ . '/../tmp/';
 
@@ -469,18 +469,25 @@ class phpbb_test_case_helpers
 		}
 
 		// Set up the a minimum config
-		if ($container->has('config'))
+		if (!isset($config))
 		{
-			$config = $container->get('config');
-		}
-		else
-		{
-			$config = new \phpbb\config\config(array());
+			if ($container->has('config'))
+			{
+				$config = $container->get('config');
+			}
+			else
+			{
+				$config = new \phpbb\config\config(array());
+			}
 		}
 		$default_config = array(
-			'allow_nocensors' => false,
+			'allow_nocensors'       => false,
 			'allowed_schemes_links' => 'http,https,ftp',
-			'smilies_path' => 'images/smilies',
+			'script_path'           => '/phpbb',
+			'server_name'           => 'localhost',
+			'server_port'           => 80,
+			'server_protocol'       => 'http://',
+			'smilies_path'          => 'images/smilies',
 		);
 		foreach ($default_config as $config_name => $config_value)
 		{
@@ -519,7 +526,6 @@ class phpbb_test_case_helpers
 			     ->will($this->test_case->returnCallback(__CLASS__ . '::format_date'));
 
 			$user->date_format = 'Y-m-d H:i:s';
-			$user->host = 'localhost';
 			$user->optionset('viewcensors', true);
 			$user->optionset('viewflash', true);
 			$user->optionset('viewimg', true);
diff --git a/tests/text_formatter/s9e/default_formatting_test.php b/tests/text_formatter/s9e/default_formatting_test.php
index b5777a42d4..82c2e1f108 100644
--- a/tests/text_formatter/s9e/default_formatting_test.php
+++ b/tests/text_formatter/s9e/default_formatting_test.php
@@ -236,12 +236,12 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case
 				'<a href="http://www.phpbb.com/community/path/to/long/url/file.ext#section" class="postlink">http://www.phpbb.com/community/path/to/ ... xt#section</a>'
 			),
 			array(
-				'http://localhost/ http://localhost/viewforum.php?f=1',
-				'<a href="http://localhost/" class="postlink">http://localhost/</a> <a href="http://localhost/viewforum.php?f=1" class="postlink">viewforum.php?f=1</a>'
+				'http://localhost/ http://localhost/phpbb/ http://localhost/phpbb/viewforum.php?f=1',
+				'<a href="http://localhost/" class="postlink">http://localhost/</a> <a href="http://localhost/phpbb/" class="postlink">http://localhost/phpbb/</a> <a href="http://localhost/phpbb/viewforum.php?f=1" class="postlink">viewforum.php?f=1</a>'
 			),
 			array(
-				'http://localhost/viewforum.php?f=1#xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
-				'<a href="http://localhost/viewforum.php?f=1#xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" class="postlink">viewforum.php?f=1#xxxxxxxxxxxxxxxxxxxxx ... xxxxxxxxxx</a>'
+				'http://localhost/phpbb/viewforum.php?f=1#xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
+				'<a href="http://localhost/phpbb/viewforum.php?f=1#xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" class="postlink">viewforum.php?f=1#xxxxxxxxxxxxxxxxxxxxx ... xxxxxxxxxx</a>'
 			),
 			array(
 				'[quote="[url=http://example.org]xxx[/url]"]...[/quote]',
diff --git a/tests/text_formatter/s9e/factory_test.php b/tests/text_formatter/s9e/factory_test.php
index c8bf595092..77f27d6547 100644
--- a/tests/text_formatter/s9e/factory_test.php
+++ b/tests/text_formatter/s9e/factory_test.php
@@ -35,7 +35,7 @@ class phpbb_textformatter_s9e_factory_test extends phpbb_database_test_case
 
 	public function get_factory()
 	{
-		global $phpbb_root_path;
+		global $config, $phpbb_root_path, $request, $user;
 		$this->cache = new phpbb_mock_cache;
 		$dal = new \phpbb\textformatter\data_access(
 			$this->new_dbal(),
@@ -55,6 +55,16 @@ class phpbb_textformatter_s9e_factory_test extends phpbb_database_test_case
 			'_foo_renderer'
 		);
 
+		// Global objects required by generate_board_url()
+		$config = new \phpbb\config\config(array(
+			'script_path'           => '/phpbb',
+			'server_name'           => 'localhost',
+			'server_port'           => 80,
+			'server_protocol'       => 'http://',
+		));
+		$request = new phpbb_mock_request;
+		$user = new phpbb_mock_user;
+
 		return $factory;
 	}
 
@@ -128,14 +138,14 @@ class phpbb_textformatter_s9e_factory_test extends phpbb_database_test_case
 	public function test_local_url()
 	{
 		global $config, $user, $request;
-		$config = array(
+		$config = new \phpbb\config\config(array(
 			'force_server_vars' => true,
 			'server_protocol' => 'http://',
 			'server_name' => 'path',
 			'server_port' => 80,
 			'script_path' => '/to',
 			'cookie_secure' => false
-		);
+		));
 		$user = new phpbb_mock_user;
 		$request = new phpbb_mock_request;
 

From ad2c032d3b748d177403fd495685977f7964f8d4 Mon Sep 17 00:00:00 2001
From: JoshyPHP <s9e.dev@gmail.com>
Date: Sun, 6 Dec 2015 22:08:00 +0100
Subject: [PATCH 05/10] [ticket/14323] Moved autolink-related functions to a
 separate helper

PHPBB3-14323
---
 .../container/services_text_formatter.yml     |   4 +
 .../textformatter/s9e/autolink_helper.php     | 105 ++++++++++++++++++
 phpBB/phpbb/textformatter/s9e/factory.php     |  43 +++++--
 phpBB/phpbb/textformatter/s9e/parser.php      |  47 --------
 .../phpbb_test_case_helpers.php               |  17 ++-
 tests/text_formatter/s9e/factory_test.php     |   1 +
 6 files changed, 150 insertions(+), 67 deletions(-)
 create mode 100644 phpBB/phpbb/textformatter/s9e/autolink_helper.php

diff --git a/phpBB/config/default/container/services_text_formatter.yml b/phpBB/config/default/container/services_text_formatter.yml
index f86d30658e..01a833aef3 100644
--- a/phpBB/config/default/container/services_text_formatter.yml
+++ b/phpBB/config/default/container/services_text_formatter.yml
@@ -26,6 +26,9 @@ services:
     text_formatter.utils:
         alias: text_formatter.s9e.utils
 
+    text_formatter.s9e.autolink_helper:
+        class: phpbb\textformatter\s9e\autolink_helper
+
     text_formatter.s9e.factory:
         class: phpbb\textformatter\s9e\factory
         arguments:
@@ -33,6 +36,7 @@ services:
             - '@cache.driver'
             - '@dispatcher'
             - '@config'
+            - '@text_formatter.s9e.autolink_helper'
             - '%text_formatter.cache.dir%'
             - '%text_formatter.cache.parser.key%'
             - '%text_formatter.cache.renderer.key%'
diff --git a/phpBB/phpbb/textformatter/s9e/autolink_helper.php b/phpBB/phpbb/textformatter/s9e/autolink_helper.php
new file mode 100644
index 0000000000..8fb171f413
--- /dev/null
+++ b/phpBB/phpbb/textformatter/s9e/autolink_helper.php
@@ -0,0 +1,105 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\textformatter\s9e;
+
+class autolink_helper
+{
+	/**
+	* Clean up and invalidate an AUTOLINK_TEXT tag if applicable
+	*
+	* @param  \s9e\TextFormatter\Parser\Tag $tag    AUTOLINK_TEXT tag
+	* @param  \s9e\TextFormatter\Parser     $parser Parser
+	* @return bool                                  Whether the tag is valid
+	*/
+	public function cleanup_tag(\s9e\TextFormatter\Parser\Tag $tag, \s9e\TextFormatter\Parser $parser)
+	{
+		// Remove the url attribute because it's not needed.
+		$tag->removeAttribute('url');
+
+		// Invalidate if the content of the tag matches the text attribute
+		$text = substr($parser->getText(), $tag->getPos(), $tag->getLen());
+
+		return ($text !== $tag->getAttribute('text'));
+	}
+
+	/**
+	* Create an AUTOLINK_TEXT tag inside of a link created by the Autolink plugin
+	*
+	* Will only apply to URL tags that do not use any markup (e.g. not "[url]")
+	* on the assumption that those tags were created by the Autolink plugin to
+	* linkify URLs found in plain text
+	*
+	* @param  \s9e\TextFormatter\Parser\Tag $tag    URL tag (start tag)
+	* @param  \s9e\TextFormatter\Parser     $parser Parser
+	* @return bool                                  Always true to indicate that the tag is valid
+	*/
+	public function generate_autolink_text_tag(\s9e\TextFormatter\Parser\Tag $tag, \s9e\TextFormatter\Parser $parser)
+	{
+		// If the tag consumes any text then we ignore it because it's not a
+		// linkified URL. Same if it's not paired with an end tag that doesn't
+		// consume any text either
+		if ($tag->getLen() > 0 || !$tag->getEndTag())
+		{
+			return true;
+		}
+
+		// Capture the text between the start tag and its end tag
+		$start  = $tag->getPos();
+		$end    = $tag->getEndTag()->getPos();
+		$length = $end - $start;
+		$text   = substr($parser->getText(), $start, $length);
+
+		// Create a tag that consumes the link's text
+		$parser->addSelfClosingTag('AUTOLINK_TEXT', $start, $length)->setAttribute('text', $text);
+
+		return true;
+	}
+
+	/**
+	* Remove the board's root URL from a the start of a string
+	*
+	* @param  \s9e\TextFormatter\Parser\Tag $tag       AUTOLINK_TEXT tag
+	* @param  string                        $board_url Forum's root URL (with trailing slash)
+	* @return bool                                     Always true to indicate that the tag is valid
+	*/
+	public function truncate_local_url(\s9e\TextFormatter\Parser\Tag $tag, $board_url)
+	{
+		$text = $tag->getAttribute('text');
+		if (stripos($text, $board_url) === 0 && strlen($text) > strlen($board_url))
+		{
+			$tag->setAttribute('text', substr($text, strlen($board_url)));
+		}
+
+		return true;
+	}
+
+	/**
+	* Truncate the replacement text set in an AUTOLINK_TEXT tag
+	*
+	* @param  \s9e\TextFormatter\Parser\Tag $tag AUTOLINK_TEXT tag
+	* @return bool                               Always true to indicate that the tag is valid
+	*/
+	public function truncate_text(\s9e\TextFormatter\Parser\Tag $tag)
+	{
+		$text = $tag->getAttribute('text');
+		if (utf8_strlen($text) > 55)
+		{
+			$text = utf8_substr($text, 0, 39) . ' ... ' . utf8_substr($text, -10);
+		}
+
+		$tag->setAttribute('text', $text);
+
+		return true;
+	}
+}
diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php
index 63e49b6dd4..736f9a9f8a 100644
--- a/phpBB/phpbb/textformatter/s9e/factory.php
+++ b/phpBB/phpbb/textformatter/s9e/factory.php
@@ -22,6 +22,11 @@ use s9e\TextFormatter\Configurator\Items\UnsafeTemplate;
 */
 class factory implements \phpbb\textformatter\cache_interface
 {
+	/**
+	* @var \phpbb\textformatter\s9e\autolink_helper
+	*/
+	protected $autolink_helper;
+
 	/**
 	* @var \phpbb\cache\driver\driver_interface
 	*/
@@ -133,12 +138,14 @@ class factory implements \phpbb\textformatter\cache_interface
 	* @param \phpbb\cache\driver\driver_interface $cache
 	* @param \phpbb\event\dispatcher_interface $dispatcher
 	* @param \phpbb\config\config $config
+	* @param \phpbb\textformatter\s9e\autolink_helper $autolink_helper
 	* @param string $cache_dir          Path to the cache dir
 	* @param string $cache_key_parser   Cache key used for the parser
 	* @param string $cache_key_renderer Cache key used for the renderer
 	*/
-	public function __construct(\phpbb\textformatter\data_access $data_access, \phpbb\cache\driver\driver_interface $cache, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\config\config $config, $cache_dir, $cache_key_parser, $cache_key_renderer)
+	public function __construct(\phpbb\textformatter\data_access $data_access, \phpbb\cache\driver\driver_interface $cache, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\config\config $config, \phpbb\textformatter\s9e\autolink_helper $autolink_helper, $cache_dir, $cache_key_parser, $cache_key_renderer)
 	{
+		$this->autolink_helper = $autolink_helper;
 		$this->cache = $cache;
 		$this->cache_dir = $cache_dir;
 		$this->cache_key_parser = $cache_key_parser;
@@ -404,19 +411,35 @@ class factory implements \phpbb\textformatter\cache_interface
 		$configurator->plugins->load('Autoemail');
 		$configurator->plugins->load('Autolink', array('matchWww' => true));
 
-		// Create a tag that will be used to display the truncated text by replacing the original
-		// content with the content of the @text attribute
-		$tag = $configurator->tags->add('AUTOLINK_TEXT');
-		$tag->attributes->add('text');
-		$tag->template = '<xsl:value-of select="@text"/>';
-
-		// Add a tag filter that replaces the text of links that were created by the Autolink plugin
+		// Add a tag filter that creates a tag that stores and replace the
+		// content of a link created by the Autolink plugin
 		$configurator->Autolink->getTag()->filterChain
-			->add(__NAMESPACE__ . '\\parser::generate_autolink_text')
+			->add(array($this->autolink_helper, 'generate_autolink_text_tag'))
+			->resetParameters()
+			->addParameterByName('tag')
+			->addParameterByName('parser');
+
+		// Create a tag that will be used to display the truncated text by
+		// replacing the original content with the content of the @text attribute
+		$tag = $configurator->tags->add('AUTOLINK_TEXT');
+		$tag->attributes->add('text');
+		$tag->attributes->add('url', array('required' => false))->filterChain->add('#url');
+		$tag->template = '<xsl:value-of select="@text"/>';
+
+		$tag->filterChain
+			->add(array($this->autolink_helper, 'truncate_local_url'))
 			->resetParameters()
 			->addParameterByName('tag')
-			->addParameterByName('parser')
 			->addParameterByValue(generate_board_url() . '/');
+		$tag->filterChain
+			->add(array($this->autolink_helper, 'truncate_text'))
+			->resetParameters()
+			->addParameterByName('tag');
+		$tag->filterChain
+			->add(array($this->autolink_helper, 'cleanup_tag'))
+			->resetParameters()
+			->addParameterByName('tag')
+			->addParameterByName('parser');
 	}
 
 	/**
diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php
index beb737c816..ffaffbc63c 100644
--- a/phpBB/phpbb/textformatter/s9e/parser.php
+++ b/phpBB/phpbb/textformatter/s9e/parser.php
@@ -393,51 +393,4 @@ class parser implements \phpbb\textformatter\parser_interface
 
 		return $url;
 	}
-
-	/**
-	* Replace the content displayed inside of a URL tag
-	*
-	* Will only apply to URL tags that do not use any markup (e.g. not "[url]")
-	* on the assumption that those tags were created by the Autolink plugin to
-	* linkify URLs found in plain text
-	*
-	* @param  \s9e\TextFormatter\Parser\Tag $url_tag   URL tag (start tag)
-	* @param  \s9e\TextFormatter\Parser     $parser    Parser
-	* @param  string                        $board_url Forum's root URL (with trailing slash)
-	* @return bool                                     Always true to indicate that the tag is valid
-	*/
-	public static function generate_autolink_text(\s9e\TextFormatter\Parser\Tag $url_tag, \s9e\TextFormatter\Parser $parser, $board_url)
-	{
-		// If the tag consumes any text then we ignore it because it's not a
-		// linkified URL. Same if it's not paired with an end tag that doesn't
-		// consume any text either
-		if ($url_tag->getLen() > 0 || !$url_tag->getEndTag())
-		{
-			return true;
-		}
-
-		// Capture the text between the start tag and its end tag
-		$start  = $url_tag->getPos();
-		$end    = $url_tag->getEndTag()->getPos();
-		$length = $end - $start;
-		$text   = substr($parser->getText(), $start, $length);
-
-		// Remove the board's root URL from the link if applicable
-		if (stripos($text, $board_url) === 0 && strlen($text) > strlen($board_url))
-		{
-			$text = substr($text, strlen($board_url));
-		}
-
-		// Truncate the text if it's longer than 55 characters
-		if (utf8_strlen($text) > 55)
-		{
-			$text = utf8_substr($text, 0, 39) . ' ... ' . utf8_substr($text, -10);
-		}
-
-		// Create a tag that consumes the link's text
-		$tag = $parser->addSelfClosingTag('AUTOLINK_TEXT', $start, $length);
-		$tag->setAttribute('text', $text);
-
-		return true;
-	}
 }
diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php
index aa58b3974b..dacf9d923f 100644
--- a/tests/test_framework/phpbb_test_case_helpers.php
+++ b/tests/test_framework/phpbb_test_case_helpers.php
@@ -469,16 +469,13 @@ class phpbb_test_case_helpers
 		}
 
 		// Set up the a minimum config
-		if (!isset($config))
+		if ($container->has('config'))
 		{
-			if ($container->has('config'))
-			{
-				$config = $container->get('config');
-			}
-			else
-			{
-				$config = new \phpbb\config\config(array());
-			}
+			$config = $container->get('config');
+		}
+		elseif (!isset($config))
+		{
+			$config = new \phpbb\config\config(array());
 		}
 		$default_config = array(
 			'allow_nocensors'       => false,
@@ -504,7 +501,7 @@ class phpbb_test_case_helpers
 		}
 
 		// Create and register the text_formatter.s9e.factory service
-		$factory = new \phpbb\textformatter\s9e\factory($dal, $cache, $dispatcher, $config, $cache_dir, $cache_key_parser, $cache_key_renderer);
+		$factory = new \phpbb\textformatter\s9e\factory($dal, $cache, $dispatcher, $config, new \phpbb\textformatter\s9e\autolink_helper, $cache_dir, $cache_key_parser, $cache_key_renderer);
 		$container->set('text_formatter.s9e.factory', $factory);
 
 		// Create a user if none was provided, and add the common lang strings
diff --git a/tests/text_formatter/s9e/factory_test.php b/tests/text_formatter/s9e/factory_test.php
index 77f27d6547..dbf28b1d38 100644
--- a/tests/text_formatter/s9e/factory_test.php
+++ b/tests/text_formatter/s9e/factory_test.php
@@ -50,6 +50,7 @@ class phpbb_textformatter_s9e_factory_test extends phpbb_database_test_case
 			$this->cache,
 			$this->dispatcher,
 			new \phpbb\config\config(array('allowed_schemes_links' => 'http,https,ftp')),
+			new \phpbb\textformatter\s9e\autolink_helper,
 			$this->get_cache_dir(),
 			'_foo_parser',
 			'_foo_renderer'

From 791c329e94283cc7fb5462c26e079a362cbd1810 Mon Sep 17 00:00:00 2001
From: JoshyPHP <s9e.dev@gmail.com>
Date: Sat, 26 Dec 2015 15:43:10 +0100
Subject: [PATCH 06/10] [ticket/14323] Fixed test data

PHPBB3-14323
---
 tests/text_processing/tickets_data/PHPBB3-9791.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/text_processing/tickets_data/PHPBB3-9791.html b/tests/text_processing/tickets_data/PHPBB3-9791.html
index cabed5b12f..3d0108c8a6 100644
--- a/tests/text_processing/tickets_data/PHPBB3-9791.html
+++ b/tests/text_processing/tickets_data/PHPBB3-9791.html
@@ -1 +1 @@
-<a href="http://www.phpbb.com/community/search.php?keywords=bogus&amp;terms=all&amp;author=&amp;fid%5B%5D=46&amp;sc=1&amp;sf=all&amp;sr=posts&amp;sk=t&amp;sd=d&amp;st=0&amp;ch=300&amp;t=0&amp;submit=Search" class="postlink">http://www.phpbb.com/community/search.php?keywords=bogus&amp;terms=all&amp;author=&amp;fid[]=46&amp;sc=1&amp;sf=all&amp;sr=posts&amp;sk=t&amp;sd=d&amp;st=0&amp;ch=300&amp;t=0&amp;submit=Search</a>
\ No newline at end of file
+<a href="http://www.phpbb.com/community/search.php?keywords=bogus&amp;terms=all&amp;author=&amp;fid%5B%5D=46&amp;sc=1&amp;sf=all&amp;sr=posts&amp;sk=t&amp;sd=d&amp;st=0&amp;ch=300&amp;t=0&amp;submit=Search" class="postlink">http://www.phpbb.com/community/search.p ... mit=Search</a>
\ No newline at end of file

From 5c8373dc20f3cef80b00304ec3b9e27fa86346e5 Mon Sep 17 00:00:00 2001
From: JoshyPHP <s9e.dev@gmail.com>
Date: Sat, 26 Dec 2015 17:01:37 +0100
Subject: [PATCH 07/10] [ticket/14323] Added comment [ci skip]

PHPBB3-14323
---
 phpBB/phpbb/textformatter/s9e/autolink_helper.php | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/phpBB/phpbb/textformatter/s9e/autolink_helper.php b/phpBB/phpbb/textformatter/s9e/autolink_helper.php
index 8fb171f413..81ebc6d029 100644
--- a/phpBB/phpbb/textformatter/s9e/autolink_helper.php
+++ b/phpBB/phpbb/textformatter/s9e/autolink_helper.php
@@ -18,6 +18,9 @@ class autolink_helper
 	/**
 	* Clean up and invalidate an AUTOLINK_TEXT tag if applicable
 	*
+	* Will invalidate the tag if its replacement text is the same as the original
+	* text and would have no visible effect
+	*
 	* @param  \s9e\TextFormatter\Parser\Tag $tag    AUTOLINK_TEXT tag
 	* @param  \s9e\TextFormatter\Parser     $parser Parser
 	* @return bool                                  Whether the tag is valid

From 909f8653ec0bf2905ed8d8a9591486f7eefe4d56 Mon Sep 17 00:00:00 2001
From: JoshyPHP <s9e.dev@gmail.com>
Date: Sun, 27 Dec 2015 16:43:45 +0100
Subject: [PATCH 08/10] [ticket/14323] Renamed AUTOLINK_TEXT to LINK_TEXT

Expanded link text shortening to [url] BBCodes with no parameters

PHPBB3-14323
---
 .../container/services_text_formatter.yml     |  8 ++---
 phpBB/phpbb/textformatter/s9e/factory.php     | 21 ++++++-----
 .../{autolink_helper.php => link_helper.php}  | 35 ++++++++-----------
 .../phpbb_test_case_helpers.php               |  2 +-
 tests/text_formatter/s9e/factory_test.php     |  2 +-
 5 files changed, 31 insertions(+), 37 deletions(-)
 rename phpBB/phpbb/textformatter/s9e/{autolink_helper.php => link_helper.php} (66%)

diff --git a/phpBB/config/default/container/services_text_formatter.yml b/phpBB/config/default/container/services_text_formatter.yml
index 01a833aef3..943a79cd65 100644
--- a/phpBB/config/default/container/services_text_formatter.yml
+++ b/phpBB/config/default/container/services_text_formatter.yml
@@ -26,9 +26,6 @@ services:
     text_formatter.utils:
         alias: text_formatter.s9e.utils
 
-    text_formatter.s9e.autolink_helper:
-        class: phpbb\textformatter\s9e\autolink_helper
-
     text_formatter.s9e.factory:
         class: phpbb\textformatter\s9e\factory
         arguments:
@@ -36,11 +33,14 @@ services:
             - '@cache.driver'
             - '@dispatcher'
             - '@config'
-            - '@text_formatter.s9e.autolink_helper'
+            - '@text_formatter.s9e.link_helper'
             - '%text_formatter.cache.dir%'
             - '%text_formatter.cache.parser.key%'
             - '%text_formatter.cache.renderer.key%'
 
+    text_formatter.s9e.link_helper:
+        class: phpbb\textformatter\s9e\link_helper
+
     text_formatter.s9e.parser:
         class: phpbb\textformatter\s9e\parser
         arguments:
diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php
index 736f9a9f8a..7fdc5afeed 100644
--- a/phpBB/phpbb/textformatter/s9e/factory.php
+++ b/phpBB/phpbb/textformatter/s9e/factory.php
@@ -23,9 +23,9 @@ use s9e\TextFormatter\Configurator\Items\UnsafeTemplate;
 class factory implements \phpbb\textformatter\cache_interface
 {
 	/**
-	* @var \phpbb\textformatter\s9e\autolink_helper
+	* @var \phpbb\textformatter\s9e\link_helper
 	*/
-	protected $autolink_helper;
+	protected $link_helper;
 
 	/**
 	* @var \phpbb\cache\driver\driver_interface
@@ -138,14 +138,14 @@ class factory implements \phpbb\textformatter\cache_interface
 	* @param \phpbb\cache\driver\driver_interface $cache
 	* @param \phpbb\event\dispatcher_interface $dispatcher
 	* @param \phpbb\config\config $config
-	* @param \phpbb\textformatter\s9e\autolink_helper $autolink_helper
+	* @param \phpbb\textformatter\s9e\link_helper $link_helper
 	* @param string $cache_dir          Path to the cache dir
 	* @param string $cache_key_parser   Cache key used for the parser
 	* @param string $cache_key_renderer Cache key used for the renderer
 	*/
-	public function __construct(\phpbb\textformatter\data_access $data_access, \phpbb\cache\driver\driver_interface $cache, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\config\config $config, \phpbb\textformatter\s9e\autolink_helper $autolink_helper, $cache_dir, $cache_key_parser, $cache_key_renderer)
+	public function __construct(\phpbb\textformatter\data_access $data_access, \phpbb\cache\driver\driver_interface $cache, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\config\config $config, \phpbb\textformatter\s9e\link_helper $link_helper, $cache_dir, $cache_key_parser, $cache_key_renderer)
 	{
-		$this->autolink_helper = $autolink_helper;
+		$this->link_helper = $link_helper;
 		$this->cache = $cache;
 		$this->cache_dir = $cache_dir;
 		$this->cache_key_parser = $cache_key_parser;
@@ -414,29 +414,28 @@ class factory implements \phpbb\textformatter\cache_interface
 		// Add a tag filter that creates a tag that stores and replace the
 		// content of a link created by the Autolink plugin
 		$configurator->Autolink->getTag()->filterChain
-			->add(array($this->autolink_helper, 'generate_autolink_text_tag'))
+			->add(array($this->link_helper, 'generate_link_text_tag'))
 			->resetParameters()
 			->addParameterByName('tag')
 			->addParameterByName('parser');
 
 		// Create a tag that will be used to display the truncated text by
 		// replacing the original content with the content of the @text attribute
-		$tag = $configurator->tags->add('AUTOLINK_TEXT');
+		$tag = $configurator->tags->add('LINK_TEXT');
 		$tag->attributes->add('text');
-		$tag->attributes->add('url', array('required' => false))->filterChain->add('#url');
 		$tag->template = '<xsl:value-of select="@text"/>';
 
 		$tag->filterChain
-			->add(array($this->autolink_helper, 'truncate_local_url'))
+			->add(array($this->link_helper, 'truncate_local_url'))
 			->resetParameters()
 			->addParameterByName('tag')
 			->addParameterByValue(generate_board_url() . '/');
 		$tag->filterChain
-			->add(array($this->autolink_helper, 'truncate_text'))
+			->add(array($this->link_helper, 'truncate_text'))
 			->resetParameters()
 			->addParameterByName('tag');
 		$tag->filterChain
-			->add(array($this->autolink_helper, 'cleanup_tag'))
+			->add(array($this->link_helper, 'cleanup_tag'))
 			->resetParameters()
 			->addParameterByName('tag')
 			->addParameterByName('parser');
diff --git a/phpBB/phpbb/textformatter/s9e/autolink_helper.php b/phpBB/phpbb/textformatter/s9e/link_helper.php
similarity index 66%
rename from phpBB/phpbb/textformatter/s9e/autolink_helper.php
rename to phpBB/phpbb/textformatter/s9e/link_helper.php
index 81ebc6d029..76948159ba 100644
--- a/phpBB/phpbb/textformatter/s9e/autolink_helper.php
+++ b/phpBB/phpbb/textformatter/s9e/link_helper.php
@@ -13,23 +13,20 @@
 
 namespace phpbb\textformatter\s9e;
 
-class autolink_helper
+class link_helper
 {
 	/**
-	* Clean up and invalidate an AUTOLINK_TEXT tag if applicable
+	* Clean up and invalidate a LINK_TEXT tag if applicable
 	*
 	* Will invalidate the tag if its replacement text is the same as the original
 	* text and would have no visible effect
 	*
-	* @param  \s9e\TextFormatter\Parser\Tag $tag    AUTOLINK_TEXT tag
+	* @param  \s9e\TextFormatter\Parser\Tag $tag    LINK_TEXT tag
 	* @param  \s9e\TextFormatter\Parser     $parser Parser
 	* @return bool                                  Whether the tag is valid
 	*/
 	public function cleanup_tag(\s9e\TextFormatter\Parser\Tag $tag, \s9e\TextFormatter\Parser $parser)
 	{
-		// Remove the url attribute because it's not needed.
-		$tag->removeAttribute('url');
-
 		// Invalidate if the content of the tag matches the text attribute
 		$text = substr($parser->getText(), $tag->getPos(), $tag->getLen());
 
@@ -37,34 +34,32 @@ class autolink_helper
 	}
 
 	/**
-	* Create an AUTOLINK_TEXT tag inside of a link created by the Autolink plugin
+	* Create a LINK_TEXT tag inside of a link
 	*
-	* Will only apply to URL tags that do not use any markup (e.g. not "[url]")
-	* on the assumption that those tags were created by the Autolink plugin to
-	* linkify URLs found in plain text
+	* Meant to only apply to linkified URLs and [url] BBCodes without a parameter
 	*
 	* @param  \s9e\TextFormatter\Parser\Tag $tag    URL tag (start tag)
 	* @param  \s9e\TextFormatter\Parser     $parser Parser
 	* @return bool                                  Always true to indicate that the tag is valid
 	*/
-	public function generate_autolink_text_tag(\s9e\TextFormatter\Parser\Tag $tag, \s9e\TextFormatter\Parser $parser)
+	public function generate_link_text_tag(\s9e\TextFormatter\Parser\Tag $tag, \s9e\TextFormatter\Parser $parser)
 	{
-		// If the tag consumes any text then we ignore it because it's not a
-		// linkified URL. Same if it's not paired with an end tag that doesn't
-		// consume any text either
-		if ($tag->getLen() > 0 || !$tag->getEndTag())
+		// Only create a LINK_TEXT tag if the start tag is paired with an end
+		// tag, which is the case with tags from the Autolink plugins and with
+		// the [url] BBCode when its content is used for the URL
+		if (!$tag->getEndTag())
 		{
 			return true;
 		}
 
 		// Capture the text between the start tag and its end tag
-		$start  = $tag->getPos();
+		$start  = $tag->getPos() + $tag->getLen();
 		$end    = $tag->getEndTag()->getPos();
 		$length = $end - $start;
 		$text   = substr($parser->getText(), $start, $length);
 
 		// Create a tag that consumes the link's text
-		$parser->addSelfClosingTag('AUTOLINK_TEXT', $start, $length)->setAttribute('text', $text);
+		$parser->addSelfClosingTag('LINK_TEXT', $start, $length)->setAttribute('text', $text);
 
 		return true;
 	}
@@ -72,7 +67,7 @@ class autolink_helper
 	/**
 	* Remove the board's root URL from a the start of a string
 	*
-	* @param  \s9e\TextFormatter\Parser\Tag $tag       AUTOLINK_TEXT tag
+	* @param  \s9e\TextFormatter\Parser\Tag $tag       LINK_TEXT tag
 	* @param  string                        $board_url Forum's root URL (with trailing slash)
 	* @return bool                                     Always true to indicate that the tag is valid
 	*/
@@ -88,9 +83,9 @@ class autolink_helper
 	}
 
 	/**
-	* Truncate the replacement text set in an AUTOLINK_TEXT tag
+	* Truncate the replacement text set in a LINK_TEXT tag
 	*
-	* @param  \s9e\TextFormatter\Parser\Tag $tag AUTOLINK_TEXT tag
+	* @param  \s9e\TextFormatter\Parser\Tag $tag LINK_TEXT tag
 	* @return bool                               Always true to indicate that the tag is valid
 	*/
 	public function truncate_text(\s9e\TextFormatter\Parser\Tag $tag)
diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php
index dacf9d923f..c4b653ec7c 100644
--- a/tests/test_framework/phpbb_test_case_helpers.php
+++ b/tests/test_framework/phpbb_test_case_helpers.php
@@ -501,7 +501,7 @@ class phpbb_test_case_helpers
 		}
 
 		// Create and register the text_formatter.s9e.factory service
-		$factory = new \phpbb\textformatter\s9e\factory($dal, $cache, $dispatcher, $config, new \phpbb\textformatter\s9e\autolink_helper, $cache_dir, $cache_key_parser, $cache_key_renderer);
+		$factory = new \phpbb\textformatter\s9e\factory($dal, $cache, $dispatcher, $config, new \phpbb\textformatter\s9e\link_helper, $cache_dir, $cache_key_parser, $cache_key_renderer);
 		$container->set('text_formatter.s9e.factory', $factory);
 
 		// Create a user if none was provided, and add the common lang strings
diff --git a/tests/text_formatter/s9e/factory_test.php b/tests/text_formatter/s9e/factory_test.php
index dbf28b1d38..8f8ec7ebc7 100644
--- a/tests/text_formatter/s9e/factory_test.php
+++ b/tests/text_formatter/s9e/factory_test.php
@@ -50,7 +50,7 @@ class phpbb_textformatter_s9e_factory_test extends phpbb_database_test_case
 			$this->cache,
 			$this->dispatcher,
 			new \phpbb\config\config(array('allowed_schemes_links' => 'http,https,ftp')),
-			new \phpbb\textformatter\s9e\autolink_helper,
+			new \phpbb\textformatter\s9e\link_helper,
 			$this->get_cache_dir(),
 			'_foo_parser',
 			'_foo_renderer'

From bcd5d8b5126e57e8c4c93a0d0c1be5e25f0185ff Mon Sep 17 00:00:00 2001
From: JoshyPHP <s9e.dev@gmail.com>
Date: Sun, 27 Dec 2015 18:39:53 +0100
Subject: [PATCH 09/10] [ticket/14323] Added tests

PHPBB3-14323
---
 tests/text_formatter/s9e/default_formatting_test.php | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/tests/text_formatter/s9e/default_formatting_test.php b/tests/text_formatter/s9e/default_formatting_test.php
index 82c2e1f108..fc6b0a65fa 100644
--- a/tests/text_formatter/s9e/default_formatting_test.php
+++ b/tests/text_formatter/s9e/default_formatting_test.php
@@ -243,6 +243,14 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case
 				'http://localhost/phpbb/viewforum.php?f=1#xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
 				'<a href="http://localhost/phpbb/viewforum.php?f=1#xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" class="postlink">viewforum.php?f=1#xxxxxxxxxxxxxxxxxxxxx ... xxxxxxxxxx</a>'
 			),
+			array(
+				'[url]http://example.org/0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0[/url]',
+				'<a href="http://example.org/0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0" class="postlink">http://example.org/0xxxxxxxxxxxxxxxxxxx ... xxxxxxxxx0</a>'
+			),
+			array(
+				'[url=http://example.org/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[/url]',
+				'<a href="http://example.org/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" class="postlink">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</a>'
+			),
 			array(
 				'[quote="[url=http://example.org]xxx[/url]"]...[/quote]',
 				'<blockquote><div><cite><a href="http://example.org" class="postlink">xxx</a> wrote:</cite>...</div></blockquote>'

From bc5d976786d60d8d33cf77fccf81ce351b59fcdc Mon Sep 17 00:00:00 2001
From: JoshyPHP <s9e.dev@gmail.com>
Date: Mon, 28 Dec 2015 04:19:21 +0100
Subject: [PATCH 10/10] [ticket/14323] Added should_shorten()

Explicitly tests a tag's markup to determine whether a link should be shortened

PHPBB3-14323
---
 phpBB/phpbb/textformatter/s9e/link_helper.php   | 17 ++++++++++++++++-
 .../s9e/default_formatting_test.php             |  4 ++++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/phpBB/phpbb/textformatter/s9e/link_helper.php b/phpBB/phpbb/textformatter/s9e/link_helper.php
index 76948159ba..0f44603dec 100644
--- a/phpBB/phpbb/textformatter/s9e/link_helper.php
+++ b/phpBB/phpbb/textformatter/s9e/link_helper.php
@@ -47,7 +47,7 @@ class link_helper
 		// Only create a LINK_TEXT tag if the start tag is paired with an end
 		// tag, which is the case with tags from the Autolink plugins and with
 		// the [url] BBCode when its content is used for the URL
-		if (!$tag->getEndTag())
+		if (!$tag->getEndTag() || !$this->should_shorten($tag, $parser->getText()))
 		{
 			return true;
 		}
@@ -64,6 +64,21 @@ class link_helper
 		return true;
 	}
 
+	/**
+	* Test whether we should shorten this tag's text
+	*
+	* Will test whether the tag either does not use any markup or uses a single
+	* [url] BBCode
+	*
+	* @param  \s9e\TextFormatter\Parser\Tag $tag  URL tag
+	* @param  string                        $text Original text
+	* @return bool
+	*/
+	protected function should_shorten(\s9e\TextFormatter\Parser\Tag $tag, $text)
+	{
+		return ($tag->getLen() === 0 || strtolower(substr($text, $tag->getPos(), $tag->getLen())) === '[url]');
+	}
+
 	/**
 	* Remove the board's root URL from a the start of a string
 	*
diff --git a/tests/text_formatter/s9e/default_formatting_test.php b/tests/text_formatter/s9e/default_formatting_test.php
index fc6b0a65fa..1f7df15434 100644
--- a/tests/text_formatter/s9e/default_formatting_test.php
+++ b/tests/text_formatter/s9e/default_formatting_test.php
@@ -247,6 +247,10 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case
 				'[url]http://example.org/0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0[/url]',
 				'<a href="http://example.org/0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0" class="postlink">http://example.org/0xxxxxxxxxxxxxxxxxxx ... xxxxxxxxx0</a>'
 			),
+			array(
+				'[URL]http://example.org/0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0[/url]',
+				'<a href="http://example.org/0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0" class="postlink">http://example.org/0xxxxxxxxxxxxxxxxxxx ... xxxxxxxxx0</a>'
+			),
 			array(
 				'[url=http://example.org/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[/url]',
 				'<a href="http://example.org/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" class="postlink">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</a>'