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
Add support for "any other tag" categories in IN BODY
  • Loading branch information
dmsnell authored and sirreal committed Dec 22, 2023
commit 2a8fc4640c33a74b0c12699d221651fafd4758dc
43 changes: 43 additions & 0 deletions src/wp-includes/html-api/class-wp-html-processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,8 @@ private function step_in_body() {
* @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody
*/
switch ( $tag_name ) {
case 'ABBR':
case 'ACRONYM':
case 'APPLET':
case 'AREA':
case 'BASE':
Expand Down Expand Up @@ -945,6 +947,47 @@ private function step_in_body() {
throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." );
}

if ( ! $this->is_tag_closer() ) {
// > Any other start tag.
$this->reconstruct_active_formatting_elements();
$this->insert_html_element( $this->state->current_token );
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;
}
}
while ( $pop_count-- > 0 ) {
$this->state->stack_of_open_elements->pop();
}
return true;
} elseif ( self::is_special( $node->node_name ) ) {
// This is a parse error, ignore the token.
return $this->step();
}
$one_shot = false;
foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) {
if ( $one_shot ) {
$node = $item;
goto in_body_any_other_end_tag_loop;
}

$one_shot = true;
}
}

$this->last_error = self::ERROR_UNSUPPORTED;
throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." );
}
Expand Down
16 changes: 0 additions & 16 deletions tests/phpunit/tests/html-api/wpHtmlProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,6 @@ public function test_get_tag_is_null_once_document_is_finished() {
$this->assertNull( $p->get_tag() );
}

/**
* Ensures that if the HTML Processor encounters inputs that it can't properly handle,
* that it stops processing the rest of the document. This prevents data corruption.
*
* @ticket 59167
*
* @covers WP_HTML_Processor::next_tag
*/
public function test_stops_processing_after_unsupported_elements() {
$p = WP_HTML_Processor::create_fragment( '<p><x-not-supported></p><p></p>' );
$p->next_tag( 'P' );
$this->assertFalse( $p->next_tag(), 'Stepped into a tag after encountering X-NOT-SUPPORTED element when it should have aborted.' );
$this->assertNull( $p->get_tag(), "Should have aborted processing, but still reported tag {$p->get_tag()} after properly failing to step into tag." );
$this->assertFalse( $p->next_tag( 'P' ), 'Stepped into normal P element after X-NOT-SUPPORTED element when it should have aborted.' );
}

/**
* Ensures that the HTML Processor maintains its internal state through seek calls.
*
Expand Down
8 changes: 4 additions & 4 deletions tests/phpunit/tests/html-api/wpHtmlProcessorBreadcrumbs.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,6 @@ public function data_unsupported_elements() {
'VIDEO',
'WBR',
'XMP', // Deprecated, use PRE instead.

// Made up elements, custom elements.
'X-NOT-AN-HTML-ELEMENT',
'HUMAN-TIME',
);

$data = array();
Expand Down Expand Up @@ -360,6 +356,10 @@ public function data_html_target_with_breadcrumbs() {
'H4 inside H2' => array( '<h2><span>Major<h4 target>Minor</h3></span>', array( 'HTML', 'BODY', 'H2', 'SPAN', 'H4' ), 1 ),
'H5 after unclosed H4 inside H2' => array( '<h2><span>Major<h4>Minor</span></h3><h5 target>', array( 'HTML', 'BODY', 'H2', 'SPAN', 'H5' ), 1 ),
'H5 after H4 inside H2' => array( '<h2><span>Major<h4>Minor</h4></span></h3><h5 target>', array( 'HTML', 'BODY', 'H5' ), 1 ),

// Custom elements.
'WP-EMOJI' => array( '<div><wp-emoji target></wp-emoji></div>', array( 'HTML', 'BODY', 'DIV', 'WP-EMOJI' ), 1 ),
'WP-EMOJI then IMG' => array( '<div><wp-emoji></wp-emoji><img target></div>', array( 'HTML', 'BODY', 'DIV', 'IMG' ), 1 ),
);
}

Expand Down