diff --git a/src/wp-includes/html-api/class-wp-html-tag-processor.php b/src/wp-includes/html-api/class-wp-html-tag-processor.php
index 68c227f221066..91f192e9a5364 100644
--- a/src/wp-includes/html-api/class-wp-html-tag-processor.php
+++ b/src/wp-includes/html-api/class-wp-html-tag-processor.php
@@ -3978,8 +3978,7 @@ public function set_modifiable_text( string $plaintext_content ): bool {
self::STATE_COMMENT === $this->parser_state &&
self::COMMENT_AS_HTML_COMMENT === $this->comment_type
) {
- // Check if the text could close the comment.
- if ( 1 === preg_match( '/^-?>|--!?>/', $plaintext_content ) ) {
+ if ( self::has_comment_closer( $plaintext_content ) ) {
_doing_it_wrong(
__METHOD__,
__( 'Comment text cannot contain a comment closer.' ),
@@ -4093,14 +4092,13 @@ public function set_modifiable_text( string $plaintext_content ): bool {
* start tag which follows `" or "--!>", or at ">" or "->" right after "' => array( '', 'Comments end in -->' ),
'Comment with --!>' => array( '', 'Invalid but legitimate comments end in --!>' ),
+ 'Comment starting with >' => array( '', '> ends an empty comment' ),
+ 'Comment starting with ->' => array( '', '-> ends an empty comment' ),
'IFRAME with ' => array( '', 'Just a ' ),
'NOEMBED with ' => array( 'Replace me', 'Just a ' ),
'NOFRAMES with ' => array( 'Replace me', 'beforeafter' ),
@@ -721,6 +729,46 @@ public static function data_unallowed_modifiable_text_updates() {
);
}
+ /**
+ * Ensures that comment text which resembles a comment closer, but cannot
+ * end the comment, is allowed.
+ *
+ * @dataProvider data_comment_text_resembling_a_closer
+ *
+ * @param string $update Text resembling, but not forming, a comment closer.
+ */
+ public function test_allows_comment_text_which_cannot_close_the_comment( string $update ): void {
+ $processor = new WP_HTML_Tag_Processor( '' );
+ $processor->next_token();
+
+ $this->assertTrue(
+ $processor->set_modifiable_text( $update ),
+ 'Should have allowed text which cannot close the comment.'
+ );
+
+ $this->assertSame(
+ "",
+ $processor->get_updated_html(),
+ 'Should have updated the comment.'
+ );
+ }
+
+ /**
+ * Data provider.
+ *
+ * @return array[]
+ */
+ public static function data_comment_text_resembling_a_closer(): array {
+ return array(
+ '> after text' => array( 'a>' ),
+ '-> after text' => array( 'a->' ),
+ '-!> at the start' => array( '-!>' ),
+ '--! before text' => array( '--!x>' ),
+ 'Spaced dashes' => array( '- ->' ),
+ 'Dashes at the end' => array( 'a--' ),
+ );
+ }
+
/**
* Ensures that raw text which resembles a closing tag, but cannot close its
* element, is allowed as modifiable text.
@@ -814,6 +862,7 @@ public static function data_script_tag_text_updates(): array {
'Tricky script open tag with \r\n' => array( '', "