From a5d56959624f512ca469b26d6c5aa05e26e96f4f Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Tue, 8 Nov 2016 11:03:56 +0100 Subject: [PATCH] Enforcing a limit of 50 smilies per parsed message Exceeding smilies will be ignored: - `` will be reverted into the textual representation - text smilies will be left untouched The limit is enforced for both types of smilies that could occur, for example having 47 smilies using `` will cause at maximum 3 text smilies to be converted into actual images. --- .../bbcode/SimpleMessageParser.class.php | 11 ++++++++-- .../input/node/HtmlInputNodeImg.class.php | 21 ++++++++++++++++++- .../node/HtmlInputNodeProcessor.class.php | 6 ++++-- .../node/HtmlInputNodeTextParser.class.php | 19 +++++++++++++++-- 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/wcfsetup/install/files/lib/system/bbcode/SimpleMessageParser.class.php b/wcfsetup/install/files/lib/system/bbcode/SimpleMessageParser.class.php index 7196737972..5a253a390b 100644 --- a/wcfsetup/install/files/lib/system/bbcode/SimpleMessageParser.class.php +++ b/wcfsetup/install/files/lib/system/bbcode/SimpleMessageParser.class.php @@ -220,9 +220,16 @@ class SimpleMessageParser extends SingletonFactory { * @return string text */ public function parseSmilies($text) { + $smileyCount = 0; foreach ($this->smilies as $code => $html) { - //$text = preg_replace('~(?)~', $html, $text); - $text = preg_replace('~(?<=^|\s)'.preg_quote(StringUtil::encodeHTML($code), '~').'(?=$|\s|
|
)~', $html, $text); + $text = preg_replace_callback('~(?<=^|\s)'.preg_quote(StringUtil::encodeHTML($code), '~').'(?=$|\s|
|
)~', function() use ($code, $html, &$smileyCount) { + if ($smileyCount === 50) { + return $code; + } + + $smileyCount++; + return $html; + }, $text); } return $text; diff --git a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeImg.class.php b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeImg.class.php index 3c5a2ef16a..2dedd889cb 100644 --- a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeImg.class.php +++ b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeImg.class.php @@ -17,6 +17,12 @@ use wcf\util\JSON; * @since 3.0 */ class HtmlInputNodeImg extends AbstractHtmlInputNode { + /** + * number of found smilies + * @var integer + */ + protected $smiliesFound = 0; + /** * @inheritDoc */ @@ -53,6 +59,8 @@ class HtmlInputNodeImg extends AbstractHtmlInputNode { * @inheritDoc */ public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) { + $this->smiliesFound = 0; + /** @var \DOMElement $element */ foreach ($elements as $element) { $class = $element->getAttribute('class'); @@ -68,6 +76,15 @@ class HtmlInputNodeImg extends AbstractHtmlInputNode { } } + /** + * Returns the number of smilies found within the message. + * + * @return integer + */ + public function getSmileyCount() { + return $this->smiliesFound; + } + /** * Replaces image element with attachment metacode element. * @@ -148,7 +165,7 @@ class HtmlInputNodeImg extends AbstractHtmlInputNode { /** @var Smiley $smiley */ $smiley = SmileyCache::getInstance()->getSmileyByCode($code); - if ($smiley === null) { + if ($smiley === null || $this->smiliesFound === 50) { $element->parentNode->insertBefore($element->ownerDocument->createTextNode($code), $element); $element->parentNode->removeChild($element); } @@ -161,6 +178,8 @@ class HtmlInputNodeImg extends AbstractHtmlInputNode { if ($smiley->smileyPath2x) $element->setAttribute('srcset', $smiley->getURL2x() . ' 2x'); else $element->removeAttribute('srcset'); + + $this->smiliesFound++; } } } diff --git a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeProcessor.class.php b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeProcessor.class.php index 82640971fb..55d4880fc0 100644 --- a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeProcessor.class.php +++ b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeProcessor.class.php @@ -63,7 +63,9 @@ class HtmlInputNodeProcessor extends AbstractHtmlNodeProcessor { $this->enforceQuoteDepth(MESSAGE_MAX_QUOTE_DEPTH); } - $this->invokeHtmlNode(new HtmlInputNodeImg()); + $imgNodeHandler = new HtmlInputNodeImg(); + $this->invokeHtmlNode($imgNodeHandler); + $smileyCount = $imgNodeHandler->getSmileyCount(); // dynamic node handlers $this->invokeNodeHandlers('wcf\system\html\input\node\HtmlInputNode', ['img', 'woltlab-metacode']); @@ -72,7 +74,7 @@ class HtmlInputNodeProcessor extends AbstractHtmlNodeProcessor { $this->trim(); // detect mentions, urls, emails and smileys - $textParser = new HtmlInputNodeTextParser($this); + $textParser = new HtmlInputNodeTextParser($this, $smileyCount); $textParser->parse(); // strip invalid class names diff --git a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeTextParser.class.php b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeTextParser.class.php index c1922cda2f..7894724c60 100644 --- a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeTextParser.class.php +++ b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeTextParser.class.php @@ -37,6 +37,12 @@ class HtmlInputNodeTextParser { */ protected $nodeStack = []; + /** + * number of found smilies + * @var integer + */ + protected $smileyCount = 0; + /** * list of smilies by smiley code * @var Smiley[] @@ -76,12 +82,15 @@ class HtmlInputNodeTextParser { * HtmlInputNodeTextParser constructor. * * @param HtmlInputNodeProcessor $htmlInputNodeProcessor + * @param integer $smileyCount */ - public function __construct(HtmlInputNodeProcessor $htmlInputNodeProcessor) { + public function __construct(HtmlInputNodeProcessor $htmlInputNodeProcessor, $smileyCount = 0) { $this->htmlInputNodeProcessor = $htmlInputNodeProcessor; $this->sourceBBCodes = HtmlBBCodeParser::getInstance()->getSourceBBCodes(); if (MODULE_SMILEY) { + $this->smileyCount = $smileyCount; + // get smilies $smilies = SmileyCache::getInstance()->getSmilies(); $categories = SmileyCache::getInstance()->getCategories(); @@ -185,7 +194,9 @@ class HtmlInputNodeTextParser { $value = $this->parseEmail($node, $value); } - $value = $this->parseSmiley($node, $value); + if ($this->smileyCount !== 50) { + $value = $this->parseSmiley($node, $value); + } if ($value !== $oldValue) { $node->textContent = $value; @@ -456,7 +467,11 @@ class HtmlInputNodeTextParser { return preg_replace_callback($smileyPattern, function($matches) use ($text) { $smileyCode = $matches[0]; + if ($this->smileyCount === 50) { + return $smileyCode; + } + $this->smileyCount++; $smiley = $this->smilies[$smileyCode]; $element = $text->ownerDocument->createElement('img'); $element->setAttribute('src', $smiley->getURL()); -- 2.20.1