WordPress.org

Make WordPress Core

Ticket #29557: miqro-29557.8.patch

File miqro-29557.8.patch, 7.3 KB (added by miqrogroove, 7 years ago)

Reduce backtracking in HTML comments.

  • src/wp-includes/formatting.php

     
    2828 * @return string The string replaced with html entities
    2929 */
    3030function wptexturize($text, $reset = false) {
    31         global $wp_cockneyreplace, $shortcode_tags;
     31        global $wp_cockneyreplace;
    3232        static $static_characters, $static_replacements, $dynamic_characters, $dynamic_replacements,
    3333                $default_no_texturize_tags, $default_no_texturize_shortcodes, $run_texturize = true;
    3434
     
    205205
    206206        // Look for shortcodes and HTML elements.
    207207
    208         $tagnames = array_keys( $shortcode_tags );
    209         $tagregexp = join( '|', array_map( 'preg_quote', $tagnames ) );
    210         $tagregexp = "(?:$tagregexp)(?![\\w-])"; // Excerpt of get_shortcode_regex().
     208        $comment_regex =
     209                        '!--'                   // Start of comment, after the <.
     210                .       '[^\-]*'                // Consume non-dashes.
     211                .       '(?:'                   // Unroll the loop: Consume everything until -- is found.
     212                .               '-[^\-]++'      // Dash followed by non-dashes.
     213                .       ')*+'                   // Loop possessively.
     214                .       '(?:'                   // End of comment. If not found, match all input.
     215                .               '--'
     216                .               '(?:\s*>)?'
     217                .       ')?';
    211218       
    212         $regex =  '/('                  // Capture the entire match.
    213                 .       '<'             // Find start of element.
    214                 .       '(?(?=!--)'     // Is this a comment?
    215                 .               '.+?--\s*>'     // Find end of comment
     219        $shortcode_regex =
     220                        '\['                    // Find start of shortcode.
     221                .       '[\/\[]?'               // Shortcodes may begin with [/ or [[
     222                .       '[^\s\/\[\]]'   // No whitespace before name.
     223                .       '[^\[\]]*+'             // Shortcodes do not contain other shortcodes. Possessive critical.
     224                .       '\]'                    // Find end of shortcode.
     225                .       '\]?';                  // Shortcodes may end with ]]
     226       
     227        $regex =
     228                        '/('                                    // Capture the entire match.
     229                .               '<'                                     // Find start of element.
     230                .               '(?(?=!--)'                     // Is this a comment?
     231                .                       $comment_regex  // Find end of comment.
     232                .               '|'
     233                .                       '[^>]+>'                // Find end of element.
     234                .               ')'
    216235                .       '|'
    217                 .               '[^>]+>'        // Find end of element
    218                 .       ')'
    219                 . '|'
    220                 .       '\['            // Find start of shortcode.
    221                 .       '\[?'           // Shortcodes may begin with [[
    222                 .       '\/?'           // Closing slash may precede name.
    223                 .       $tagregexp      // Only match registered shortcodes, because performance.
    224                 .       '[^\[\]]*'      // Shortcodes do not contain other shortcodes.
    225                 .       '\]'            // Find end of shortcode.
    226                 .       '\]?'           // Shortcodes may end with ]]
    227                 . ')/s';
     236                .               $shortcode_regex        // Find shortcodes.
     237                .       ')/s';
    228238
    229239        $textarr = preg_split( $regex, $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
    230240
     
    231241        foreach ( $textarr as &$curl ) {
    232242                // Only call _wptexturize_pushpop_element if $curl is a delimiter.
    233243                $first = $curl[0];
    234                 if ( '<' === $first && '>' === substr( $curl, -1 ) ) {
    235                         // This is an HTML delimiter.
     244                if ( '<' === $first && '<!--' === substr( $curl, 0, 4 ) ) {
     245                        // This is an HTML comment delimeter.
    236246
    237                         if ( '<!--' !== substr( $curl, 0, 4 ) ) {
    238                                 _wptexturize_pushpop_element( $curl, $no_texturize_tags_stack, $no_texturize_tags );
    239                         }
     247                        continue;
    240248
     249                } elseif ( '<' === $first && '>' === substr( $curl, -1 ) ) {
     250                        // This is an HTML element delimiter.
     251
     252                        _wptexturize_pushpop_element( $curl, $no_texturize_tags_stack, $no_texturize_tags );
     253
    241254                } elseif ( '' === trim( $curl ) ) {
    242255                        // This is a newline between delimiters.  Performance improves when we check this.
    243256
    244257                        continue;
    245258
    246                 } elseif ( '[' === $first && 1 === preg_match( '/^\[\[?\/?' . $tagregexp . '[^\[\]]*\]\]?$/', $curl ) ) {
     259                } elseif ( '[' === $first && 1 === preg_match( '/^' . $shortcode_regex . '$/', $curl ) ) {
    247260                        // This is a shortcode delimiter.
    248261
    249262                        if ( '[[' !== substr( $curl, 0, 2 ) && ']]' !== substr( $curl, -2 ) ) {
  • src/wp-includes/shortcodes.php

     
    231231        $tagregexp = join( '|', array_map('preg_quote', $tagnames) );
    232232
    233233        // WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcode_tag()
    234         // Also, see shortcode_unautop() and shortcode.js and wptexturize().
     234        // Also, see shortcode_unautop() and shortcode.js.
    235235        return
    236236                  '\\['                              // Opening bracket
    237237                . '(\\[?)'                           // 1: Optional second opening bracket for escaping shortcodes: [[tag]]
  • tests/phpunit/tests/formatting/WPTexturize.php

     
    11881188        function data_tag_avoidance() {
    11891189                return array(
    11901190                        array(
     1191                                '[ ... ]',
     1192                                '[ &#8230; ]',
     1193                        ),
     1194                        array(
    11911195                                '[ is it wise to <a title="allow user content ] here? hmm"> maybe </a> ]',
    11921196                                '[ is it wise to <a title="allow user content ] here? hmm"> maybe </a> ]',
    11931197                        ),
    11941198                        array(
     1199                                '[is it wise to <a title="allow user content ] here? hmm"> maybe </a> ]', // HTML corruption is a known bug.  See tickets #12690 and #29557.
     1200                                '[is it wise to <a title="allow user content ] here? hmm&#8221;> maybe </a> ]',
     1201                        ),
     1202                        array(
     1203                                '[caption - is it wise to <a title="allow user content ] here? hmm"> maybe </a> ]',
     1204                                '[caption - is it wise to <a title="allow user content ] here? hmm&#8221;> maybe </a> ]',
     1205                        ),
     1206                        array(
    11951207                                '[ photos by <a href="http://example.com/?a[]=1&a[]=2"> this guy </a> ]',
    11961208                                '[ photos by <a href="http://example.com/?a[]=1&#038;a[]=2"> this guy </a> ]',
    11971209                        ),
    11981210                        array(
     1211                                '[photos by <a href="http://example.com/?a[]=1&a[]=2"> this guy </a>]',
     1212                                '[photos by <a href="http://example.com/?a[]=1&#038;a[]=2"> this guy </a>]',
     1213                        ),
     1214                        array(
    11991215                                '[gallery ...]',
    12001216                                '[gallery ...]',
    12011217                        ),
     
    12121228                                '[/gallery ...]',
    12131229                        ),
    12141230                        array(
    1215                                 '[...]...[/...]', // These are potentially usable shortcodes.
    1216                                 '[&#8230;]&#8230;[/&#8230;]',
    1217                         ),
    1218                         array(
    12191231                                '[[gallery]]...[[/gallery]]', // Shortcode parsing will ignore the inner ]...[ part and treat this as a single escaped shortcode.
    12201232                                '[[gallery]]&#8230;[[/gallery]]',
    12211233                        ),
     
    12241236                                '[[[gallery]]]&#8230;[[[/gallery]]]',
    12251237                        ),
    12261238                        array(
    1227                                 '[gal>ery ...]',
    1228                                 '[gal>ery &#8230;]',
    1229                         ),
    1230                         array(
    12311239                                '[gallery ...',
    12321240                                '[gallery &#8230;',
    12331241                        ),
     
    13041312                                '<!-- ... -- >',
    13051313                        ),
    13061314                        array(
     1315                                '<!-- ...', // An unclosed comment is still a comment.
     1316                                '<!-- ...',
     1317                        ),
     1318                        array(
    13071319                                '<!-- <br /> [gallery] ... -->',
    13081320                                '<!-- <br /> [gallery] ... -->',
    13091321                        ),
     
    17271739                        ),
    17281740                        array(
    17291741                                '[code ...]...[/code]', // code is not a registered shortcode.
    1730                                 '[code &#8230;]&#8230;[/code]',
     1742                                '[code ...]...[/code]',
    17311743                        ),
    17321744                        array(
    17331745                                '[hello ...]...[/hello]', // hello is not a registered shortcode.
    1734                                 '[hello &#8230;]&#8230;[/hello]',
     1746                                '[hello ...]&#8230;[/hello]',
    17351747                        ),
    17361748                        array(
     1749                                '[...]...[/...]', // These are potentially usable shortcodes.
     1750                                '[...]&#8230;[/...]',
     1751                        ),
     1752                        array(
     1753                                '[gal>ery ...]',
     1754                                '[gal>ery ...]',
     1755                        ),
     1756                        array(
     1757                                '[randomthing param="test"]',
     1758                                '[randomthing param="test"]',
     1759                        ),
     1760                        array(
    17371761                                '[[audio]...[/audio]...', // These are potentially usable shortcodes.  Unfortunately, the meaning of [[audio] is ambiguous unless we run the entire shortcode regexp.
    17381762                                '[[audio]&#8230;[/audio]&#8230;',
    17391763                        ),