Make WordPress Core


Ignore:
Timestamp:
11/28/2024 02:25:51 PM (18 months ago)
Author:
Bernhard Reiter
Message:

HTML API: Make non-body fragment creation methods private.

The current implementation of create_fragment (and the underlying create_fragment_at_current_node) allows passing in a context that might result in a tree that cannot be represented by HTML. For example, a user might use <p> as context, and attempt to create a fragment that also consists of a paragraph element, <p>like this. This would result in a paragraph node nested inside another -- something that can never result from parsing HTML.

To prevent this, this changeset makes create_fragment_at_current_node private and limits create_fragment to only <body> as context, while a comprehensive solution to allow other contexts is being worked on.

Follow-up to [59444], [59467].
Props jonsurrell, dmsnell, bernhard-reiter.
Fixes #62584.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/html-api/wpHtmlProcessorHtml5lib.php

    r59467 r59469  
    139139     */
    140140    private static function should_skip_test( ?string $test_context_element, string $test_name ): bool {
     141        if ( null !== $test_context_element && 'body' !== $test_context_element ) {
     142            return true;
     143        }
     144
    141145        if ( array_key_exists( $test_name, self::SKIP_TESTS ) ) {
    142146            return true;
     
    154158     */
    155159    private static function build_tree_representation( ?string $fragment_context, string $html ) {
    156         if ( $fragment_context ) {
    157             /*
    158              * If the string of characters starts with "svg ", the context
    159              * element is in the SVG namespace and the substring after
    160              * "svg " is the local name. If the string of characters starts
    161              * with "math ", the context element is in the MathML namespace
    162              * and the substring after "math " is the local name.
    163              * Otherwise, the context element is in the HTML namespace and
    164              * the string is the local name.
    165              */
    166             if ( str_starts_with( $fragment_context, 'svg ' ) ) {
    167                 $tag_name = substr( $fragment_context, 4 );
    168                 if ( 'svg' === $tag_name ) {
    169                     $fragment_context_html = '<svg>';
    170                 } else {
    171                     $fragment_context_html = "<svg><{$tag_name}>";
    172                 }
    173             } elseif ( str_starts_with( $fragment_context, 'math ' ) ) {
    174                 $tag_name = substr( $fragment_context, 5 );
    175                 if ( 'math' === $tag_name ) {
    176                     $fragment_context_html = '<math>';
    177                 } else {
    178                     $fragment_context_html = "<math><{$tag_name}>";
    179                 }
    180             } else {
    181                 // Tags that only appear in tables need a special case.
    182                 if ( in_array(
    183                     $fragment_context,
    184                     array(
    185                         'caption',
    186                         'col',
    187                         'colgroup',
    188                         'tbody',
    189                         'td',
    190                         'tfoot',
    191                         'th',
    192                         'thead',
    193                         'tr',
    194                     ),
    195                     true
    196                 ) ) {
    197                     $fragment_context_html = "<table><{$fragment_context}>";
    198                 } else {
    199                     $fragment_context_html = "<{$fragment_context}>";
    200                 }
    201             }
    202 
    203             $processor = WP_HTML_Processor::create_fragment( $html, $fragment_context_html );
    204 
    205             if ( null === $processor ) {
    206                 throw new WP_HTML_Unsupported_Exception( "Could not create a parser with the given fragment context: {$fragment_context}.", '', 0, '', array(), array() );
    207             }
    208         } else {
    209             $processor = WP_HTML_Processor::create_full_parser( $html );
    210             if ( null === $processor ) {
    211                 throw new Exception( 'Could not create a full parser.' );
    212             }
     160        $processor = $fragment_context
     161            ? WP_HTML_Processor::create_fragment( $html, "<{$fragment_context}>" )
     162            : WP_HTML_Processor::create_full_parser( $html );
     163        if ( null === $processor ) {
     164            throw new WP_HTML_Unsupported_Exception( "Could not create a parser with the given fragment context: {$fragment_context}.", '', 0, '', array(), array() );
    213165        }
    214166
Note: See TracChangeset for help on using the changeset viewer.