aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/phpbb/textformatter
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/phpbb/textformatter')
-rw-r--r--phpBB/phpbb/textformatter/s9e/bbcode_merger.php180
-rw-r--r--phpBB/phpbb/textformatter/s9e/factory.php9
-rw-r--r--phpBB/phpbb/textformatter/s9e/parser.php6
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;