diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php
index e1979a27821..30a6c94fc1d 100644
--- a/phpBB/phpbb/textformatter/s9e/factory.php
+++ b/phpBB/phpbb/textformatter/s9e/factory.php
@@ -364,6 +364,12 @@ function ($m)
';
$tag->template = '' . str_replace('class="emoji"', 'class="emoji smilies"', $tag->template) . '';
+ // Reject shortcodes that consist of raw codepoints in hexadecimal such as ":123c:",
+ // which commonly appear as segments of IPv6 addresses
+ $tag->filterChain
+ ->append(__NAMESPACE__ . '\\parser::filter_emoji')
+ ->addParameterByName('tagText');
+
/**
* Modify the s9e\TextFormatter configurator after the default settings are set
*
diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php
index 590afc0ebcf..749e11d86cf 100644
--- a/phpBB/phpbb/textformatter/s9e/parser.php
+++ b/phpBB/phpbb/textformatter/s9e/parser.php
@@ -301,6 +301,25 @@ public function set_vars(array $vars)
}
}
+ /**
+ * Filter an EMOJI tag to reject shortcodes that consist of raw codepoints
+ *
+ * Sequences of hexadecimal digits between colons such as ":123c:" commonly
+ * appear as segments of IPv6 addresses and should remain plain text rather
+ * than be rendered as an emoji image
+ *
+ * @param Tag $tag The EMOJI tag
+ * @param string $tag_text Original text consumed by the tag
+ * @return void
+ */
+ static public function filter_emoji(Tag $tag, $tag_text)
+ {
+ if (preg_match('/^:[0-3][0-9a-f]{3,4}(?:-[0-9a-f]{4,5})*:$/D', $tag_text))
+ {
+ $tag->invalidate();
+ }
+ }
+
/**
* Filter a flash object's height
*
diff --git a/tests/text_formatter/s9e/default_formatting_test.php b/tests/text_formatter/s9e/default_formatting_test.php
index 97b04c2fb7d..2442373a907 100644
--- a/tests/text_formatter/s9e/default_formatting_test.php
+++ b/tests/text_formatter/s9e/default_formatting_test.php
@@ -320,6 +320,26 @@ function ($container)
$container->get('text_formatter.renderer')->set_viewsmilies(false);
}
),
+ array(
+ // PHPBB-17655 - Segments of IPv6 addresses should not be rendered as emoji
+ 'IPv6: 2a09:bac3:616e:123c::1d1:f0',
+ 'IPv6: 2a09:bac3:616e:123c::1d1:f0'
+ ),
+ array(
+ 'IPv6: 2607:fb90:ec1d:0e17:e0c6:af94:1224:28a8',
+ 'IPv6: 2607:fb90:ec1d:0e17:e0c6:af94:1224:28a8'
+ ),
+ array(
+ // Raw codepoint shortcodes are rejected as they cannot be told apart
+ // from segments of IPv6 addresses
+ 'Codepoints: :264d: :1f600: :1234:',
+ 'Codepoints: :264d: :1f600: :1234:'
+ ),
+ array(
+ // Emoji shortnames keep working
+ 'Shortname: :joy:',
+ 'Shortname:
'
+ ),
);
}
}