Commit 91155452a1 for wordpress.org
commit 91155452a1832decf1c59c507213bc369a2954c1
Author: westonruter <westonruter@git.wordpress.org>
Date: Fri Oct 9 04:56:48 2026 +0000
HTML API: Remove unreachable code from HTML Processor.
The `bail()` method in `WP_HTML_Processor` always throws, and it has been documented as returning `never` since r61699. The `return false;` sentinels added after its calls in r59001, the `break` statements following a `goto`, and the trailing `bail()` calls at the end of methods whose every path already returns could therefore never run, and PHPStan reported them as unreachable. They are removed. Where a sentinel guarded against a future code path falling off the end of a method, PHPStan now catches that case instead by reporting a missing return.
In `step_in_foreign_content()`, end tags are now handled in an `else` branch rather than by re-checking `is_tag_closer()`, which was always true at that point. This lets both PHPStan and IDEs see that every path returns, so the trailing `bail()` is no longer needed.
The remaining `break` statements after a `bail()` call in a `switch` are kept. PHPCS cannot tell that `bail()` never returns, so without a `break` it treats the case as falling through and misreports the indentation of the comment above the next case. They remain in the baseline, along with two other unreachable statements which mirror steps of the HTML specification.
The outer loop of the adoption agency algorithm is likewise kept, along with its safety budget, as scaffolding for the parts of the algorithm which are not yet supported. Since r64237 PHPStan has reported the loop's two comparisons as constant. Rather than leaving them in baselines that are meant to be emptied, they are now ignored in `phpstan.neon.dist` with an explanation, and the two baseline files are deleted.
Developed in https://github.com/WordPress/wordpress-develop/pull/14090.
Follow-up to r58836, r59001, r61699, r63023, r64237.
Props westonruter, dmsnell, jonsurrell.
See #65817.
Built from https://develop.svn.wordpress.org/trunk@64250
git-svn-id: http://core.svn.wordpress.org/trunk@63401 1a063a9b-81f0-0310-95a4-ce76da25c4cd
diff --git a/wp-includes/html-api/class-wp-html-processor.php b/wp-includes/html-api/class-wp-html-processor.php
index c278cca8b0..9eceb18729 100644
--- a/wp-includes/html-api/class-wp-html-processor.php
+++ b/wp-includes/html-api/class-wp-html-processor.php
@@ -1585,7 +1585,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
return $this->step();
}
goto initial_anything_else;
- break;
/*
* > A comment token
@@ -1678,7 +1677,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
return $this->step();
}
goto before_html_anything_else;
- break;
/*
* > A start tag whose tag name is "html"
@@ -1700,7 +1698,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
* > Act as described in the "anything else" entry below.
*/
goto before_html_anything_else;
- break;
}
/*
@@ -1760,7 +1757,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
return $this->step();
}
goto before_head_anything_else;
- break;
/*
* > A comment token
@@ -1805,7 +1801,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
case '-BODY':
case '-HTML':
goto before_head_anything_else;
- break;
}
if ( $is_closer ) {
@@ -1861,7 +1856,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
}
goto in_head_anything_else;
- break;
/*
* > A comment token
@@ -1993,7 +1987,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
* > Act as described in the "anything else" entry below.
*/
goto in_head_anything_else;
- break;
/*
* > A start tag whose tag name is "template"
@@ -2086,7 +2079,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
}
goto in_head_noscript_anything_else;
- break;
/*
* > A DOCTYPE token
@@ -2190,7 +2182,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
return true;
}
goto after_head_anything_else;
- break;
/*
* > A comment token
@@ -2279,7 +2270,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
* > Act as described in the "anything else" entry below.
*/
goto after_head_anything_else;
- break;
}
/*
@@ -2783,28 +2773,27 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
$this->state->stack_of_open_elements->remove_node( $node );
return true;
- } else {
- /*
- * > If the stack of open elements does not have a form element in scope,
- * > then this is a parse error; return and ignore the token.
- *
- * Note that unlike in the clause above, this is checking for any FORM in scope.
- */
- if ( ! $this->state->stack_of_open_elements->has_element_in_scope( 'FORM' ) ) {
- // Parse error: ignore the token.
- return $this->step();
- }
+ }
- $this->generate_implied_end_tags();
+ /*
+ * > If the stack of open elements does not have a form element in scope,
+ * > then this is a parse error; return and ignore the token.
+ *
+ * Note that unlike in the clause above, this is checking for any FORM in scope.
+ */
+ if ( ! $this->state->stack_of_open_elements->has_element_in_scope( 'FORM' ) ) {
+ // Parse error: ignore the token.
+ return $this->step();
+ }
- if ( ! $this->state->stack_of_open_elements->current_node_is( 'FORM' ) ) {
- // @todo Indicate a parse error once it's possible. This error does not impact the logic here.
- }
+ $this->generate_implied_end_tags();
- $this->state->stack_of_open_elements->pop_until( 'FORM' );
- return true;
+ if ( ! $this->state->stack_of_open_elements->current_node_is( 'FORM' ) ) {
+ // @todo Indicate a parse error once it's possible. This error does not impact the logic here.
}
- break;
+
+ $this->state->stack_of_open_elements->pop_until( 'FORM' );
+ return true;
/*
* > An end tag whose tag name is "p"
@@ -3366,10 +3355,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
*/
return $this->in_body_any_other_end_tag();
}
-
- $this->bail( 'Should not have been able to reach end of IN BODY processing. Check HTML API code.' );
- // This unnecessary return prevents tools from inaccurately reporting type errors.
- return false;
}
/**
@@ -3418,8 +3403,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
}
$this->bail( 'Should not have been able to reach end of "any other end tag" IN BODY processing. Check HTML API code.' );
- // This unnecessary return prevents tools from inaccurately reporting type errors.
- return false;
}
/**
@@ -3496,7 +3479,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
// Non-whitespace would trigger fostering, unsupported at this time.
$this->bail( 'Foster parenting is not supported.' );
- break;
}
break;
@@ -3821,7 +3803,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
}
goto in_column_group_anything_else;
- break;
/*
* > A comment token
@@ -4382,7 +4363,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
return $this->step_in_body();
}
goto after_body_anything_else;
- break;
/*
* > A comment token
@@ -4705,7 +4685,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
return $this->step_in_body();
}
goto after_after_body_anything_else;
- break;
}
/*
@@ -4984,20 +4963,18 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
$this->state->stack_of_open_elements->pop();
}
return true;
- }
-
- /*
- * > An end tag whose name is "script", if the current node is an SVG script element.
- */
- if ( $this->is_tag_closer() && 'SCRIPT' === $this->state->current_token->node_name && 'svg' === $this->state->current_token->namespace ) {
- $this->state->stack_of_open_elements->pop();
- return true;
- }
+ } else {
+ /*
+ * > An end tag whose name is "script", if the current node is an SVG script element.
+ */
+ if ( 'SCRIPT' === $this->state->current_token->node_name && 'svg' === $this->state->current_token->namespace ) {
+ $this->state->stack_of_open_elements->pop();
+ return true;
+ }
- /*
- * > Any other end tag
- */
- if ( $this->is_tag_closer() ) {
+ /*
+ * > Any other end tag
+ */
$node = $this->state->stack_of_open_elements->current_node();
if ( $tag_name !== $node->node_name ) {
// @todo Indicate a parse error once it's possible.
@@ -5097,10 +5074,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
$this->bail( "Unaware of the requested parsing mode: '{$this->state->insertion_mode}'." );
}
}
-
- $this->bail( 'Should not have been able to reach end of IN FOREIGN CONTENT processing. Check HTML API code.' );
- // This unnecessary return prevents tools from inaccurately reporting type errors.
- return false;
}
/*
@@ -6388,8 +6361,6 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
}
$this->bail( 'Should not have reached end of HTML Integration Point detection: check HTML API code.' );
- // This unnecessary return prevents tools from inaccurately reporting type errors.
- return false;
}
/**
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 65548bbf74..c397c2a3a0 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
-$wp_version = '7.2-alpha-64249';
+$wp_version = '7.2-alpha-64250';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.