Tentative de régler le bordel

This commit is contained in:
Gauvain Boiché
2020-03-31 15:58:31 +02:00
parent a1864c0414
commit 459b46df7b
345 changed files with 10758 additions and 4066 deletions

View File

@@ -0,0 +1,54 @@
<?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;
interface acp_utils_interface
{
/**
* There is an issue with the definition
*/
const BBCODE_STATUS_INVALID_DEFINITION = 'invalid_definition';
/**
* There is an issue with the template
*/
const BBCODE_STATUS_INVALID_TEMPLATE = 'invalid_template';
/**
* The BBCode is valid and can be safely used by anyone
*/
const BBCODE_STATUS_SAFE = 'safe';
/**
* The BBCode is valid but may be unsafe to use
*/
const BBCODE_STATUS_UNSAFE = 'unsafe';
/**
* Analyse given BBCode definition for issues and safeness
*
* Required elements in the return array:
* - status: see BBCODE_STATUS_* constants
*
* Optional elements in the return array:
* - name: Name of the BBCode based on the definition. Required if status is "safe".
* - error_text: Textual description of the issue in plain text or as a L_* string.
* - error_html: Visual description of the issue in HTML.
*
* @param string $definition BBCode definition, e.g. [b]{TEXT}[/b]
* @param string $template BBCode template, e.g. <b>{TEXT}</b>
* @return array
*/
public function analyse_bbcode(string $definition, string $template): array;
}

View File

@@ -0,0 +1,67 @@
<?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\acp_utils_interface;
use s9e\TextFormatter\Configurator\Exceptions\UnsafeTemplateException;
class acp_utils implements acp_utils_interface
{
/**
* @var factory $factory
*/
protected $factory;
/**
* @param factory $factory
*/
public function __construct(factory $factory)
{
$this->factory = $factory;
}
/**
* {@inheritdoc}
*/
public function analyse_bbcode(string $definition, string $template): array
{
$configurator = $this->factory->get_configurator();
$return = ['status' => self::BBCODE_STATUS_SAFE];
// Capture and normalize the BBCode name manually because there's no easy way to retrieve
// it in TextFormatter <= 2.x
if (preg_match('(\\[([-\\w]++))', $definition, $m))
{
$return['name'] = strtoupper($m[1]);
}
try
{
$configurator->BBCodes->addCustom($definition, $template);
}
catch (UnsafeTemplateException $e)
{
$return['status'] = self::BBCODE_STATUS_UNSAFE;
$return['error_text'] = $e->getMessage();
$return['error_html'] = $e->highlightNode('<span class="highlight">');
}
catch (\Exception $e)
{
$return['status'] = (preg_match('(xml|xpath|xsl)i', $e->getMessage())) ? self::BBCODE_STATUS_INVALID_TEMPLATE : self::BBCODE_STATUS_INVALID_DEFINITION;
$return['error_text'] = $e->getMessage();
}
return $return;
}
}

View File

@@ -14,7 +14,7 @@
namespace phpbb\textformatter\s9e;
use phpbb\textformatter\s9e\factory;
use s9e\TextFormatter\Configurator\Helpers\TemplateHelper;
use s9e\TextFormatter\Configurator\Helpers\TemplateLoader;
use s9e\TextFormatter\Configurator\Items\UnsafeTemplate;
class bbcode_merger
@@ -50,7 +50,7 @@ class bbcode_merger
$with = $this->create_bbcode($with);
// Select the appropriate strategy for merging this BBCode
if ($this->is_content_bbcode($without, $with))
if (!$this->is_optional_bbcode($without, $with) && $this->is_content_bbcode($without, $with))
{
$merged = $this->merge_content_bbcode($without, $with);
}
@@ -91,9 +91,9 @@ class bbcode_merger
*/
protected function indent_template($template)
{
$dom = TemplateHelper::loadTemplate($template);
$dom = TemplateLoader::load($template);
$dom->formatOutput = true;
$template = TemplateHelper::saveTemplate($dom);
$template = TemplateLoader::save($dom);
// Remove the first level of indentation if the template starts with whitespace
if (preg_match('(^\\n +)', $template, $m))
@@ -107,12 +107,12 @@ class bbcode_merger
/**
* Test whether the two definitions form a "content"-style BBCode
*
* Such BBCodes include the [URL] BBCode, which uses its text content as
* 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
* @return bool
*/
protected function is_content_bbcode(array $without, array $with)
{
@@ -122,6 +122,22 @@ class bbcode_merger
&& preg_match('(>[^<]*?' . preg_quote($m[1]) . '[^>]*?<)s', $without['template']));
}
/**
* Test whether the two definitions form BBCode with an optional attribute
*
* @param array $without BBCode definition without an attribute
* @param array $with BBCode definition with an attribute
* @return bool
*/
protected function is_optional_bbcode(array $without, array $with)
{
// Remove the default attribute from the definition
$with['usage'] = preg_replace('(=[^\\]]++)', '', $with['usage']);
// Test whether both definitions are the same, regardless of case
return strcasecmp($without['usage'], $with['usage']) === 0;
}
/**
* Merge the two BBCode definitions of a "content"-style BBCode
*
@@ -131,7 +147,7 @@ class bbcode_merger
*/
protected function merge_content_bbcode(array $without, array $with)
{
// Convert [X={X}] into [X={X;useContent}]
// Convert [x={X}] into [x={X;useContent}]
$usage = preg_replace('(\\})', ';useContent}', $with['usage'], 1);
// Use the template from the definition that uses an attribute
@@ -143,7 +159,7 @@ class bbcode_merger
/**
* Merge the two BBCode definitions of a BBCode with an optional argument
*
* Such BBCodes include the [QUOTE] BBCode, which takes 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

View File

@@ -89,6 +89,8 @@ class factory implements \phpbb\textformatter\cache_interface
author={TEXT1;optional}
post_id={UINT;optional}
post_url={URL;optional;postFilter=#false}
msg_id={UINT;optional}
msg_url={URL;optional;postFilter=#false}
profile_url={URL;optional;postFilter=#false}
time={UINT;optional}
url={URL;optional}
@@ -110,7 +112,7 @@ class factory implements \phpbb\textformatter\cache_interface
'i' => '<span style="font-style: italic"><xsl:apply-templates/></span>',
'u' => '<span style="text-decoration: underline"><xsl:apply-templates/></span>',
'img' => '<img src="{IMAGEURL}" class="postimage" alt="{L_IMAGE}"/>',
'size' => '<span style="font-size: {FONTSIZE}%; line-height: normal"><xsl:apply-templates/></span>',
'size' => '<span><xsl:attribute name="style"><xsl:text>font-size: </xsl:text><xsl:value-of select="substring(@size, 1, 4)"/><xsl:text>%; line-height: normal</xsl:text></xsl:attribute><xsl:apply-templates/></span>',
'color' => '<span style="color: {COLOR}"><xsl:apply-templates/></span>',
'email' => '<a>
<xsl:attribute name="href">

View File

@@ -61,7 +61,7 @@ class link_helper
$text = substr($parser->getText(), $start, $length);
// Create a tag that consumes the link's text and make it depends on this tag
$link_text_tag = $parser->addSelfClosingTag('LINK_TEXT', $start, $length);
$link_text_tag = $parser->addSelfClosingTag('LINK_TEXT', $start, $length, 10);
$link_text_tag->setAttribute('text', $text);
$tag->cascadeInvalidationTo($link_text_tag);
}

View File

@@ -15,6 +15,7 @@ namespace phpbb\textformatter\s9e;
use s9e\TextFormatter\Parser\AttributeFilters\UrlFilter;
use s9e\TextFormatter\Parser\Logger;
use s9e\TextFormatter\Parser\Tag;
/**
* s9e\TextFormatter\Parser adapter
@@ -219,7 +220,7 @@ class parser implements \phpbb\textformatter\parser_interface
{
$errors[] = array($msg, $context['max_' . strtolower($m[1])]);
}
else if ($msg === 'Tag is disabled')
else if ($msg === 'Tag is disabled' && $this->is_a_bbcode($context['tag']))
{
$name = strtolower($context['tag']->getName());
$errors[] = array('UNAUTHORISED_BBCODE', '[' . $name . ']');
@@ -342,7 +343,7 @@ class parser implements \phpbb\textformatter\parser_interface
return false;
}
if ($size < 1)
if ($size < 1 || !is_numeric($size))
{
return false;
}
@@ -396,4 +397,21 @@ class parser implements \phpbb\textformatter\parser_interface
return $url;
}
/**
* Test whether given tag consumes text that looks like BBCode-styled markup
*
* @param Tag $tag Original tag
* @return bool
*/
protected function is_a_bbcode(Tag $tag)
{
if ($tag->getLen() < 3)
{
return false;
}
$markup = substr($this->parser->getText(), $tag->getPos(), $tag->getLen());
return (bool) preg_match('(^\\[\\w++.*?\\]$)s', $markup);
}
}

View File

@@ -20,6 +20,11 @@ class quote_helper
*/
protected $post_url;
/**
* @var string Base URL for a private message link, uses {MSG_ID} as placeholder
*/
protected $msg_url;
/**
* @var string Base URL for a profile link, uses {USER_ID} as placeholder
*/
@@ -40,6 +45,7 @@ class quote_helper
public function __construct(\phpbb\user $user, $root_path, $php_ext)
{
$this->post_url = append_sid($root_path . 'viewtopic.' . $php_ext, 'p={POST_ID}#p{POST_ID}', false);
$this->msg_url = append_sid($root_path . 'ucp.' . $php_ext, 'i=pm&mode=view&p={MSG_ID}', false);
$this->profile_url = append_sid($root_path . 'memberlist.' . $php_ext, 'mode=viewprofile&u={USER_ID}', false);
$this->user = $user;
}
@@ -52,26 +58,26 @@ class quote_helper
*/
public function inject_metadata($xml)
{
$post_url = $this->post_url;
$profile_url = $this->profile_url;
$user = $this->user;
return \s9e\TextFormatter\Utils::replaceAttributes(
$xml,
'QUOTE',
function ($attributes) use ($post_url, $profile_url, $user)
function ($attributes)
{
if (isset($attributes['post_id']))
{
$attributes['post_url'] = str_replace('{POST_ID}', $attributes['post_id'], $post_url);
$attributes['post_url'] = str_replace('{POST_ID}', $attributes['post_id'], $this->post_url);
}
if (isset($attributes['msg_id']))
{
$attributes['msg_url'] = str_replace('{MSG_ID}', $attributes['msg_id'], $this->msg_url);
}
if (isset($attributes['time']))
{
$attributes['date'] = $user->format_date($attributes['time']);
$attributes['date'] = $this->user->format_date($attributes['time']);
}
if (isset($attributes['user_id']))
{
$attributes['profile_url'] = str_replace('{USER_ID}', $attributes['user_id'], $profile_url);
$attributes['profile_url'] = str_replace('{USER_ID}', $attributes['user_id'], $this->profile_url);
}
return $attributes;