WordPress.org

Make WordPress Core

Ticket #29557: miqro-29557.5.patch

File miqro-29557.5.patch, 9.6 KB (added by miqrogroove, 5 years ago)

Attempt to fix #29608 and further simplify regex to avoid crashes.

  • src/wp-includes/formatting.php

     
    2828 * @return string The string replaced with html entities
    2929 */
    3030function wptexturize($text, $reset = false) {
    31         global $wp_cockneyreplace;
     31        global $wp_cockneyreplace, $shortcode_tags;
    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().
     211       
    208212        $regex =  '/('                  // Capture the entire match.
    209213                .       '<'             // Find start of element.
    210214                .       '(?(?=!--)'     // Is this a comment?
     
    215219                . '|'
    216220                .       '\['            // Find start of shortcode.
    217221                .       '\[?'           // Shortcodes may begin with [[
    218                 .       '(?:'
    219                 .               '[^\[\]<>]'     // Shortcodes do not contain other shortcodes.
    220                 .       '|'
    221                 .               '<[^>]+>'       // HTML elements permitted. Prevents matching ] before >.
    222                 .       ')++'
     222                .       '\/?'           // Closing slash may precede name.
     223                .       $tagregexp      // Only match registered shortcodes, because performance.
     224                .       '[^\[\]]*'      // Shortcodes do not contain other shortcodes.
    223225                .       '\]'            // Find end of shortcode.
    224226                .       '\]?'           // Shortcodes may end with ]]
    225227                . ')/s';
     
    241243
    242244                        continue;
    243245
    244                 } elseif ( '[' === $first && 1 === preg_match( '/^\[(?:[^\[\]<>]|<[^>]+>)++\]$/', $curl ) ) {
     246                } elseif ( '[' === $first && 1 === preg_match( '/^\[\[?\/?' . $tagregexp . '[^\[\]]*\]\]?$/', $curl ) ) {
    245247                        // This is a shortcode delimiter.
    246248
    247                         _wptexturize_pushpop_element( $curl, $no_texturize_shortcodes_stack, $no_texturize_shortcodes );
     249                        if ( '[[' !== substr( $curl, 0, 2 ) && ']]' !== substr( $curl, -2 ) ) {
     250                                // Looks like a normal shortcode.
     251                                _wptexturize_pushpop_element( $curl, $no_texturize_shortcodes_stack, $no_texturize_shortcodes );
     252                        } else {
     253                                // Looks like an escaped shortcode.
     254                                // Do not texturize.
     255                                // Do not push to the shortcodes stack.
     256                                continue;
     257                        }
    248258
    249                 } elseif ( '[' === $first && 1 === preg_match( '/^\[\[?(?:[^\[\]<>]|<[^>]+>)++\]\]?$/', $curl ) ) {
    250                         // This is an escaped shortcode delimiter.
    251 
    252                         // Do not texturize.
    253                         // Do not push to the shortcodes stack.
    254 
    255                         continue;
    256 
    257259                } elseif ( empty( $no_texturize_shortcodes_stack ) && empty( $no_texturize_tags_stack ) ) {
    258260                        // This is neither a delimiter, nor is this content inside of no_texturize pairs.  Do texturize.
    259261
     
    313315
    314316        // Parse out the tag name.
    315317        $space = strpos( $text, ' ' );
    316         if ( FALSE === $space ) {
     318        if ( false === $space ) {
    317319                $space = -1;
    318320        } else {
    319321                $space -= $name_offset;
  • 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.
     234        // Also, see shortcode_unautop() and shortcode.js and wptexturize().
    235235        return
    236236                  '\\['                              // Opening bracket
    237237                . '(\\[?)'                           // 1: Optional second opening bracket for escaping shortcodes: [[tag]]
  • tests/phpunit/tests/formatting/WPTexturize.php

     
    1111
    1212        function test_disable() {
    1313                $this->assertEquals('<pre>---</pre>', wptexturize('<pre>---</pre>'));
    14                 $this->assertEquals('[a]a&#8211;b[code]---[/code]a&#8211;b[/a]', wptexturize('[a]a--b[code]---[/code]a--b[/a]'));
    1514                $this->assertEquals('<pre><code></code>--</pre>', wptexturize('<pre><code></code>--</pre>'));
    1615
    1716                $this->assertEquals( '<code>---</code>',     wptexturize( '<code>---</code>'     ) );
     
    12091208                                '[gallery ...]]',
    12101209                        ),
    12111210                        array(
    1212                                 '[/...]', // This would actually be ignored by the shortcode system.  The decision to not texturize it is intentional, if not correct.
    1213                                 '[/...]',
     1211                                '[/gallery ...]', // This would actually be ignored by the shortcode system.  The decision to not texturize it is intentional, if not correct.
     1212                                '[/gallery ...]',
    12141213                        ),
    12151214                        array(
    12161215                                '[...]...[/...]', // These are potentially usable shortcodes.
    1217                                 '[...]&#8230;[/...]',
     1216                                '[&#8230;]&#8230;[/&#8230;]',
    12181217                        ),
    12191218                        array(
    1220                                 '[[...]]...[[/...]]', // Shortcode parsing will ignore the inner ]...[ part and treat this as a single escaped shortcode.
    1221                                 '[[...]]&#8230;[[/...]]',
     1219                                '[[gallery]]...[[/gallery]]', // Shortcode parsing will ignore the inner ]...[ part and treat this as a single escaped shortcode.
     1220                                '[[gallery]]&#8230;[[/gallery]]',
    12221221                        ),
    12231222                        array(
    1224                                 '[[[...]]]...[[[/...]]]', // Again, shortcode parsing matches, but only the [[...] and [/...]] parts.
    1225                                 '[[[...]]]&#8230;[[[/...]]]',
     1223                                '[[[gallery]]]...[[[/gallery]]]', // Again, shortcode parsing matches, but only the [[gallery] and [/gallery]] parts.
     1224                                '[[[gallery]]]&#8230;[[[/gallery]]]',
    12261225                        ),
    12271226                        array(
    1228                                 '[[code]...[/code]...', // These are potentially usable shortcodes.  Unfortunately, the meaning of [[code] is ambiguous unless we run the entire shortcode regexp.
    1229                                 '[[code]&#8230;[/code]&#8230;',
    1230                         ),
    1231                         array(
    1232                                 '[code]...[/code]]...', // These are potentially usable shortcodes.  Unfortunately, the meaning of [/code]] is ambiguous unless we run the entire shortcode regexp.
    1233                                 '[code]...[/code]]...', // This test would not pass in 3.9 because the extra brace was always ignored by texturize.
    1234                         ),
    1235                         array(
    12361227                                '[gal>ery ...]',
    12371228                                '[gal>ery &#8230;]',
    12381229                        ),
     
    13451336                                '[ but also catches the <b>styled &#8220;[quote]&#8221; here</b> ]',
    13461337                        ),
    13471338                        array(
    1348                                 '[Let\'s get crazy<input>[plugin code="<a href=\'?a[]=100\'>hello</a>"]</input>world]',
    1349                                 '[Let&#8217;s get crazy<input>[plugin code="<a href=\'?a[]=100\'>hello</a>"]</input>world]',
     1339                                '[Let\'s get crazy<input>[caption code="<a href=\'?a[]=100\'>hello</a>"]</input>world]', // caption shortcode is invalid here because it contains [] chars.
     1340                                '[Let&#8217;s get crazy<input>[caption code=&#8221;<a href=\'?a[]=100\'>hello</a>&#8220;]</input>world]',
    13501341                        ),
    13511342                );
    13521343        }
     
    16981689                                '<code>hello</span>---</span>',
    16991690                        ),
    17001691                        array(
    1701                                 '<span>hello[/code]---</span>',
    1702                                 '<span>hello[/code]&#8212;</span>',
     1692                                '<span><code>hello</code>---</span>',
     1693                                '<span><code>hello</code>&#8212;</span>',
    17031694                        ),
    17041695                        array(
    1705                                 '[/code]hello<span>---</span>',
    1706                                 '[/code]hello<span>&#8212;</span>',
     1696                                '<code>hello</code>world<span>---</span>',
     1697                                '<code>hello</code>world<span>&#8212;</span>',
    17071698                        ),
     1699                );
     1700        }
     1701
     1702        /**
     1703         * Test disabling shortcode texturization.
     1704         *
     1705         * @ticket 29557
     1706         * @dataProvider data_unregistered_shortcodes
     1707         */
     1708        function test_unregistered_shortcodes( $input, $output ) {
     1709                add_filter( 'no_texturize_shortcodes', array( $this, 'filter_shortcodes' ), 10, 1 );
     1710       
     1711                $output = $this->assertEquals( $output, wptexturize( $input ) );
     1712       
     1713                remove_filter( 'no_texturize_shortcodes', array( $this, 'filter_shortcodes' ), 10, 1 );
     1714                return $output;
     1715        }
     1716       
     1717        function filter_shortcodes( $disabled ) {
     1718                $disabled[] = 'audio';
     1719                return $disabled;
     1720        }
     1721
     1722        function data_unregistered_shortcodes() {
     1723                return array(
    17081724                        array(
    1709                                 '[code]hello[/code]---</span>',
    1710                                 '[code]hello[/code]&#8212;</span>',
     1725                                '[a]a--b[audio]---[/audio]a--b[/a]',
     1726                                '[a]a&#8211;b[audio]---[/audio]a&#8211;b[/a]',
    17111727                        ),
    17121728                        array(
    1713                                 '<span>hello</span>---[code]',
    1714                                 '<span>hello</span>&#8212;[code]',
     1729                                '[code ...]...[/code]', // code is not a registered shortcode.
     1730                                '[code &#8230;]&#8230;[/code]',
    17151731                        ),
    17161732                        array(
    1717                                 '<span>hello[code]---</span>',
    1718                                 '<span>hello[code]---</span>',
     1733                                '[hello ...]...[/hello]', // hello is not a registered shortcode.
     1734                                '[hello &#8230;]&#8230;[/hello]',
    17191735                        ),
    17201736                        array(
    1721                                 '[code]hello<span>---</span>',
    1722                                 '[code]hello<span>---</span>',
     1737                                '[[audio]...[/audio]...', // These are potentially usable shortcodes.  Unfortunately, the meaning of [[audio] is ambiguous unless we run the entire shortcode regexp.
     1738                                '[[audio]&#8230;[/audio]&#8230;',
    17231739                        ),
    17241740                        array(
    1725                                 '[code]hello</span>---</span>',
    1726                                 '[code]hello</span>---</span>',
     1741                                '[audio]...[/audio]]...', // These are potentially usable shortcodes.  Unfortunately, the meaning of [/audio]] is ambiguous unless we run the entire shortcode regexp.
     1742                                '[audio]...[/audio]]...', // This test would not pass in 3.9 because the extra brace was always ignored by texturize.
    17271743                        ),
     1744                        array(
     1745                                '<span>hello[/audio]---</span>',
     1746                                '<span>hello[/audio]&#8212;</span>',
     1747                        ),
     1748                        array(
     1749                                '[/audio]hello<span>---</span>',
     1750                                '[/audio]hello<span>&#8212;</span>',
     1751                        ),
     1752                        array(
     1753                                '[audio]hello[/audio]---</span>',
     1754                                '[audio]hello[/audio]&#8212;</span>',
     1755                        ),
     1756                        array(
     1757                                '<span>hello</span>---[audio]',
     1758                                '<span>hello</span>&#8212;[audio]',
     1759                        ),
     1760                        array(
     1761                                '<span>hello[audio]---</span>',
     1762                                '<span>hello[audio]---</span>',
     1763                        ),
     1764                        array(
     1765                                '[audio]hello<span>---</span>',
     1766                                '[audio]hello<span>---</span>',
     1767                        ),
     1768                        array(
     1769                                '[audio]hello</span>---</span>',
     1770                                '[audio]hello</span>---</span>',
     1771                        ),
    17281772                );
    17291773        }
    17301774}
     1775 No newline at end of file