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 5e2ee114ae9e6..7a53fbea1e273 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
@@ -1431,8 +1431,15 @@ private function skip_script_data(): bool {
continue;
}
- // Everything of interest past here starts with "<".
- if ( $at + 1 >= $doc_length || '<' !== $html[ $at++ ] ) {
+ if ( $at + 1 >= $doc_length ) {
+ return false;
+ }
+
+ /*
+ * Everything of interest past here starts with "<".
+ * Check this character and advance position regardless.
+ */
+ if ( '<' !== $html[ $at++ ] ) {
continue;
}
diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php
index fceaaddb04af6..637aa38751688 100644
--- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php
+++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php
@@ -2875,4 +2875,32 @@ public function insert_after( $new_html ) {
'Should have properly applied the update from in front of the cursor.'
);
}
+
+ /**
+ * Test an infinite loop bugfix in incomplete script tag parsing.
+ *
+ * @small
+ *
+ * @ticket 61810
+ */
+ public function test_script_tag_processing_no_infinite_loop_final_dash() {
+ $processor = new WP_HTML_Tag_Processor( '