diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 55f955f2c1a9a..aa6c86c1195ea 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -989,8 +989,6 @@ public function expects_closer( ?WP_HTML_Token $node = null ): ?bool { * * @since 6.4.0 * - * @throws Exception When unable to allocate a bookmark for the next token in the input HTML document. - * * @see self::PROCESS_NEXT_NODE * @see self::REPROCESS_CURRENT_NODE * @@ -1040,8 +1038,13 @@ public function step( $node_to_process = self::PROCESS_NEXT_NODE ): bool { $token_name = $this->get_token_name(); if ( self::REPROCESS_CURRENT_NODE !== $node_to_process ) { + $bookmark_name = $this->bookmark_token(); + if ( false === $bookmark_name ) { + return false; + } + $this->state->current_token = new WP_HTML_Token( - $this->bookmark_token(), + $bookmark_name, $token_name, $this->has_self_closing_flag(), $this->release_internal_bookmark_on_destruct @@ -1600,7 +1603,9 @@ private function step_before_html(): bool { * > Switch the insertion mode to "before head", then reprocess the token. */ before_html_anything_else: - $this->insert_virtual_node( 'HTML' ); + if ( ! $this->insert_virtual_node( 'HTML' ) ) { + return false; + } $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HEAD; return $this->step( self::REPROCESS_CURRENT_NODE ); } @@ -1697,7 +1702,11 @@ private function step_before_head(): bool { * > Insert an HTML element for a "head" start tag token with no attributes. */ before_head_anything_else: - $this->state->head_element = $this->insert_virtual_node( 'HEAD' ); + $head_element = $this->insert_virtual_node( 'HEAD' ); + if ( ! $head_element ) { + return false; + } + $this->state->head_element = $head_element; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD; return $this->step( self::REPROCESS_CURRENT_NODE ); } @@ -2166,7 +2175,9 @@ private function step_after_head(): bool { * > Insert an HTML element for a "body" start tag token with no attributes. */ after_head_anything_else: - $this->insert_virtual_node( 'BODY' ); + if ( ! $this->insert_virtual_node( 'BODY' ) ) { + return false; + } $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); } @@ -3318,7 +3329,9 @@ private function step_in_table(): bool { * > Insert an HTML element for a "colgroup" start tag token with no attributes, * > then switch the insertion mode to "in column group". */ - $this->insert_virtual_node( 'COLGROUP' ); + if ( ! $this->insert_virtual_node( 'COLGROUP' ) ) { + return false; + } $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; return $this->step( self::REPROCESS_CURRENT_NODE ); @@ -3344,7 +3357,9 @@ private function step_in_table(): bool { * > Insert an HTML element for a "tbody" start tag token with no attributes, * > then switch the insertion mode to "in table body". */ - $this->insert_virtual_node( 'TBODY' ); + if ( ! $this->insert_virtual_node( 'TBODY' ) ) { + return false; + } $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); @@ -3699,7 +3714,9 @@ private function step_in_table_body(): bool { case '+TD': // @todo Indicate a parse error once it's possible. $this->state->stack_of_open_elements->clear_to_table_body_context(); - $this->insert_virtual_node( 'TR' ); + if ( ! $this->insert_virtual_node( 'TR' ) ) { + return false; + } $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; return $this->step( self::REPROCESS_CURRENT_NODE ); @@ -5100,14 +5117,12 @@ private function step_in_foreign_content(): bool { * @since 6.4.0 * @since 6.5.0 Renamed from bookmark_tag() to bookmark_token(). * - * @throws Exception When unable to allocate requested bookmark. - * * @return string|false Name of created bookmark, or false if unable to create. */ private function bookmark_token() { if ( ! parent::set_bookmark( ++$this->bookmark_counter ) ) { $this->last_error = self::ERROR_EXCEEDED_MAX_BOOKMARKS; - throw new Exception( 'could not allocate bookmark' ); + return false; } return "{$this->bookmark_counter}"; @@ -6290,11 +6305,14 @@ private function insert_foreign_element( WP_HTML_Token $token, bool $only_add_to * @param string $token_name Name of token to create and insert into the stack of open elements. * @param string|null $bookmark_name Optional. Name to give bookmark for created virtual node. * Defaults to auto-creating a bookmark name. - * @return WP_HTML_Token Newly-created virtual token. + * @return WP_HTML_Token|false Newly-created virtual token or false on failure. */ - private function insert_virtual_node( $token_name, $bookmark_name = null ): WP_HTML_Token { + private function insert_virtual_node( $token_name, $bookmark_name = null ) { $here = $this->bookmarks[ $this->state->current_token->bookmark_name ]; $name = $bookmark_name ?? $this->bookmark_token(); + if ( false === $name ) { + return false; + } $this->bookmarks[ $name ] = new WP_HTML_Span( $here->start, 0 ); diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor.php b/tests/phpunit/tests/html-api/wpHtmlProcessor.php index 13e0728ca912a..32ed8b92b7fdb 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor.php @@ -1068,7 +1068,7 @@ public function test_ensure_next_token_method_extensibility( $html, $expected_to /** * Ensure that lowercased tag_name query matches tags case-insensitively. * - * @group 62427 + * @ticket 62427 */ public function test_next_tag_lowercase_tag_name() { // The upper case