Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Refactor closing tag loop, eliminate goto
  • Loading branch information
dmsnell committed Dec 22, 2023
commit 2cab6cf3250f284c3acec22f4330a41f98416eca
9 changes: 0 additions & 9 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -250,15 +250,6 @@
<exclude-pattern>/wp-tests-config-sample\.php</exclude-pattern>
</rule>

<!-- Exclude forbidding goto in the HTML Processor, which mimics algorithms that are written
this way in the HTML specification, and these particular algorithms are complex and
highly imperative. Avoiding the goto introduces a number of risks that could make it
more difficult to maintain the relationship to the standard, lead to subtle differences
in the parsing, and distance the code from its standard. -->
<rule ref="Generic.PHP.DiscourageGoto.Found">
<exclude-pattern>/wp-includes/html-api/class-wp-html-processor\.php</exclude-pattern>
</rule>

<!-- Exclude sample config from modernization to prevent breaking CI workflows based on WP-CLI scaffold.
See: https://core.trac.wordpress.org/ticket/48082#comment:16 -->
<rule ref="Modernize.FunctionCalls.Dirname.FileConstant">
Expand Down
47 changes: 22 additions & 25 deletions src/wp-includes/html-api/class-wp-html-processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -953,37 +953,34 @@ private function step_in_body() {
return true;
} else {
// > Any other end tag
$node = $this->state->stack_of_open_elements->current_node();

in_body_any_other_end_tag_loop:
if ( $tag_name === $node->node_name ) {
$this->generate_implied_end_tags( $tag_name );
if ( $node !== $this->state->stack_of_open_elements->current_node() ) {
// @todo Record parse error: this error doesn't impact parsing.
}
$pop_count = 0;
foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) {
++$pop_count;
if ( $node === $item ) {
break;
}
/*
* Find the corresponding tag opener in the stack of open elements, if
* it exists before reaching a special element, which provides a kind
* of boundary in the stack. For example, a `</custom-tag>` should not
* close anything beyond its containing `P` or `DIV` element.
*/
foreach ( $this->state->stack_of_open_elements->walk_up() as $node ) {
if ( $tag_name === $node->node_name ) {
break;
}
while ( $pop_count-- > 0 ) {
$this->state->stack_of_open_elements->pop();

if ( self::is_special( $node->node_name ) ) {
// This is a parse error, ignore the token.
return $this->step();
}
return true;
} elseif ( self::is_special( $node->node_name ) ) {
// This is a parse error, ignore the token.
return $this->step();
}
$one_shot = false;

$this->generate_implied_end_tags( $tag_name );
if ( $node !== $this->state->stack_of_open_elements->current_node() ) {
// @todo Record parse error: this error doesn't impact parsing.
}

foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) {
if ( $one_shot ) {
$node = $item;
goto in_body_any_other_end_tag_loop;
$this->state->stack_of_open_elements->pop();
if ( $node === $item ) {
return true;
}

$one_shot = true;
}
}

Expand Down