diff options
Diffstat (limited to 'phpBB/phpbb/textformatter')
| -rw-r--r-- | phpBB/phpbb/textformatter/s9e/bbcode_merger.php | 180 | ||||
| -rw-r--r-- | phpBB/phpbb/textformatter/s9e/factory.php | 9 | ||||
| -rw-r--r-- | phpBB/phpbb/textformatter/s9e/parser.php | 6 | 
3 files changed, 187 insertions, 8 deletions
| diff --git a/phpBB/phpbb/textformatter/s9e/bbcode_merger.php b/phpBB/phpbb/textformatter/s9e/bbcode_merger.php new file mode 100644 index 0000000000..72b1473751 --- /dev/null +++ b/phpBB/phpbb/textformatter/s9e/bbcode_merger.php @@ -0,0 +1,180 @@ +<?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; + +use phpbb\textformatter\s9e\factory; +use s9e\TextFormatter\Configurator\Helpers\TemplateHelper; +use s9e\TextFormatter\Configurator\Items\UnsafeTemplate; + +class bbcode_merger +{ +	/** +	* @var \s9e\TextFormatter\Configurator $configurator Configurator instance used to inspect BBCodes +	*/ +	protected $configurator; + +	/** +	* @param \phpbb\textformatter\s9e\factory $factory +	*/ +	public function __construct(factory $factory) +	{ +		$this->configurator = $factory->get_configurator(); +	} + +	/** +	* Merge two BBCode definitions +	* +	* All of the arrays contain a "usage" element and a "template" element +	* +	* @param  array $without BBCode definition without an attribute +	* @param  array $with    BBCode definition with an attribute +	* @return array          Merged definition +	*/ +	public function merge_bbcodes(array $without, array $with) +	{ +		$without = $this->create_bbcode($without); +		$with    = $this->create_bbcode($with); + +		// Select the appropriate strategy for merging this BBCode +		if ($this->is_content_bbcode($without, $with)) +		{ +			$merged = $this->merge_content_bbcode($without, $with); +		} +		else +		{ +			$merged = $this->merge_optional_bbcode($without, $with); +		} + +		$merged['template'] = $this->normalize_template($merged['template']); + +		return $merged; +	} + +	/** +	* Create a custom BBCode for inspection +	* +	* @param  array $definition Original BBCode definition +	* @return array             Updated definition containing a BBCode object and a Tag +	*/ +	protected function create_bbcode(array $definition) +	{ +		$bbcode = $this->configurator->BBCodes->addCustom( +			$definition['usage'], +			new UnsafeTemplate($definition['template']) +		); + +		$definition['bbcode'] = $bbcode; +		$definition['tag']    = $this->configurator->tags[$bbcode->tagName]; + +		return $definition; +	} + +	/** +	* Indent given template for readability +	* +	* @param  string $template +	* @return string +	*/ +	protected function indent_template($template) +	{ +		$dom = TemplateHelper::loadTemplate($template); +		$dom->formatOutput = true; +		$template = TemplateHelper::saveTemplate($dom); + +		// Remove the first level of indentation if the template starts with whitespace +		if (preg_match('(^\\n +)', $template, $m)) +		{ +			$template = str_replace($m[0], "\n", $template); +		} + +		return trim($template); +	} + +	/** +	* Test whether the two definitions form a "content"-style BBCode +	* +	* Such BBCodes include the [URL] BBCode, which uses its text content as +	* attribute if none is provided +	* +	* @param  array $without BBCode definition without an attribute +	* @param  array $with    BBCode definition with an attribute +	* @return array          Merged definition +	*/ +	protected function is_content_bbcode(array $without, array $with) +	{ +		// Test whether we find the same non-TEXT token between "]" and "[" in the usage +		// as between ">" and "<" in the template +		return (preg_match('(\\]\\s*(\\{(?!TEXT)[^}]+\\})\\s*\\[)', $without['usage'], $m) +			&& preg_match('(>[^<]*?' . preg_quote($m[1]) . '[^>]*?<)s', $without['template'])); +	} + +	/** +	* Merge the two BBCode definitions of a "content"-style BBCode +	* +	* @param  array $without BBCode definition without an attribute +	* @param  array $with    BBCode definition with an attribute +	* @return array          Merged definition +	*/ +	protected function merge_content_bbcode(array $without, array $with) +	{ +		// Convert [X={X}] into [X={X;useContent}] +		$usage = preg_replace('(\\})', ';useContent}', $with['usage'], 1); + +		// Use the template from the definition that uses an attribute +		$template = $with['tag']->template; + +		return ['usage' => $usage, 'template' => $template]; +	} + +	/** +	* Merge the two BBCode definitions of a BBCode with an optional argument +	* +	* Such BBCodes include the [QUOTE] BBCode, which takes an optional argument +	* but otherwise does not behave differently +	* +	* @param  array $without BBCode definition without an attribute +	* @param  array $with    BBCode definition with an attribute +	* @return array          Merged definition +	*/ +	protected function merge_optional_bbcode(array $without, array $with) +	{ +		// Convert [X={X}] into [X={X?}] +		$usage = preg_replace('(\\})', '?}', $with['usage'], 1); + +		// Build a template for both versions +		$template = '<xsl:choose><xsl:when test="@' . $with['bbcode']->defaultAttribute . '">' . $with['tag']->template . '</xsl:when><xsl:otherwise>' . $without['tag']->template . '</xsl:otherwise></xsl:choose>'; + +		return ['usage' => $usage, 'template' => $template]; +	} + +	/** +	* Normalize a template +	* +	* @param  string $template +	* @return string +	*/ +	protected function normalize_template($template) +	{ +		// Normalize the template to simplify it +		$template = $this->configurator->templateNormalizer->normalizeTemplate($template); + +		// Convert xsl:value-of elements back to {L_} tokens where applicable +		$template = preg_replace('(<xsl:value-of select="\\$(L_\\w+)"/>)', '{$1}', $template); + +		// Beautify the template +		$template = $this->indent_template($template); + +		return $template; +	} +} diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index d5ad8283d9..1e85856898 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -78,7 +78,7 @@ class factory implements \phpbb\textformatter\cache_interface  		'b'     => '[B]{TEXT}[/B]',  		'code'  => '[CODE lang={IDENTIFIER;optional}]{TEXT}[/CODE]',  		'color' => '[COLOR={COLOR}]{TEXT}[/COLOR]', -		'email' => '[EMAIL={EMAIL;useContent} subject={TEXT;optional;postFilter=rawurlencode} body={TEXT;optional;postFilter=rawurlencode}]{TEXT}[/EMAIL]', +		'email' => '[EMAIL={EMAIL;useContent} subject={TEXT1;optional;postFilter=rawurlencode} body={TEXT2;optional;postFilter=rawurlencode}]{TEXT}[/EMAIL]',  		'flash' => '[FLASH={NUMBER1},{NUMBER2} width={NUMBER1;postFilter=#flashwidth} height={NUMBER2;postFilter=#flashheight} url={URL;useContent} /]',  		'i'     => '[I]{TEXT}[/I]',  		'img'   => '[IMG src={IMAGEURL;useContent}]', @@ -266,12 +266,13 @@ class factory implements \phpbb\textformatter\cache_interface  			->addParameterByName('logger')  			->addParameterByName('max_img_height')  			->addParameterByName('max_img_width') -			->markAsSafeAsURL(); +			->markAsSafeAsURL() +			->setJS('UrlFilter.filter');  		// Add default BBCodes  		foreach ($this->get_default_bbcodes($configurator) as $bbcode)  		{ -			$configurator->BBCodes->addCustom($bbcode['usage'], $bbcode['template']); +			$configurator->BBCodes->addCustom($bbcode['usage'], new UnsafeTemplate($bbcode['template']));  		}  		if (isset($configurator->tags['QUOTE']))  		{ @@ -355,8 +356,6 @@ class factory implements \phpbb\textformatter\cache_interface  		$configurator->registeredVars['max_img_width'] = 0;  		// Load the Emoji plugin and modify its tag's template to obey viewsmilies -		$configurator->Emoji->omitImageSize(); -		$configurator->Emoji->useSVG();  		$tag = $configurator->Emoji->getTag();  		$tag->template = '<xsl:choose><xsl:when test="$S_VIEWSMILIES">' . str_replace('class="emoji"', 'class="emoji smilies"', $tag->template) . '</xsl:when><xsl:otherwise><xsl:value-of select="."/></xsl:otherwise></xsl:choose>'; diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 05ddfffa11..3698dca224 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -13,7 +13,7 @@  namespace phpbb\textformatter\s9e; -use s9e\TextFormatter\Parser\BuiltInFilters; +use s9e\TextFormatter\Parser\AttributeFilters\UrlFilter;  use s9e\TextFormatter\Parser\Logger;  /** @@ -196,7 +196,7 @@ class parser implements \phpbb\textformatter\parser_interface  	public function get_errors()  	{  		$errors = array(); -		foreach ($this->parser->getLogger()->get() as $entry) +		foreach ($this->parser->getLogger()->getLogs() as $entry)  		{  			list(, $msg, $context) = $entry; @@ -365,7 +365,7 @@ class parser implements \phpbb\textformatter\parser_interface  	static public function filter_img_url($url, array $url_config, Logger $logger, $max_height, $max_width)  	{  		// Validate the URL -		$url = BuiltInFilters::filterUrl($url, $url_config, $logger); +		$url = UrlFilter::filter($url, $url_config, $logger);  		if ($url === false)  		{  			return false; | 
