Make WordPress Core

Changeset 29748


Ignore:
Timestamp:
09/17/2014 03:13:24 PM (10 years ago)
Author:
wonderboymusic
Message:

wptexturize() improvements:

  • Expand the wptexturize() RegEx to include the list of registered shortcodes.
  • Avoid backtracking after [ chars by not filtering params in registered shortcodes. This will cause escaped shortcodes and their params to become texturized if not registered.
  • Registered shortcode params will never be texturized, even when escaped.
  • Move all tests involving unregistered shortcodes to a new and improved unit.
  • Update one test involving HTML within shortcode params.

Props miqrogroove.
See #29557.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/formatting.php

    r29715 r29748  
    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;
     
    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.
     
    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 ]]
     
    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 );
    248 
    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;
     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            }
    256258
    257259        } elseif ( empty( $no_texturize_shortcodes_stack ) && empty( $no_texturize_tags_stack ) ) {
     
    314316    // Parse out the tag name.
    315317    $space = strpos( $text, ' ' );
    316     if ( FALSE === $space ) {
     318    if ( false === $space ) {
    317319        $space = -1;
    318320    } else {
  • trunk/src/wp-includes/shortcodes.php

    r29207 r29748  
    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
  • trunk/tests/phpunit/tests/formatting/WPTexturize.php

    r28971 r29748  
    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
     
    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;[/...]',
    1218             ),
    1219             array(
    1220                 '[[...]]...[[/...]]', // Shortcode parsing will ignore the inner ]...[ part and treat this as a single escaped shortcode.
    1221                 '[[...]]&#8230;[[/...]]',
    1222             ),
    1223             array(
    1224                 '[[[...]]]...[[[/...]]]', // Again, shortcode parsing matches, but only the [[...] and [/...]] parts.
    1225                 '[[[...]]]&#8230;[[[/...]]]',
    1226             ),
    1227             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.
     1216                '[&#8230;]&#8230;[/&#8230;]',
     1217            ),
     1218            array(
     1219                '[[gallery]]...[[/gallery]]', // Shortcode parsing will ignore the inner ]...[ part and treat this as a single escaped shortcode.
     1220                '[[gallery]]&#8230;[[/gallery]]',
     1221            ),
     1222            array(
     1223                '[[[gallery]]]...[[[/gallery]]]', // Again, shortcode parsing matches, but only the [[gallery] and [/gallery]] parts.
     1224                '[[[gallery]]]&#8230;[[[/gallery]]]',
    12341225            ),
    12351226            array(
     
    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        );
     
    16991690            ),
    17001691            array(
    1701                 '<span>hello[/code]---</span>',
    1702                 '<span>hello[/code]&#8212;</span>',
    1703             ),
    1704             array(
    1705                 '[/code]hello<span>---</span>',
    1706                 '[/code]hello<span>&#8212;</span>',
    1707             ),
    1708             array(
    1709                 '[code]hello[/code]---</span>',
    1710                 '[code]hello[/code]&#8212;</span>',
    1711             ),
    1712             array(
    1713                 '<span>hello</span>---[code]',
    1714                 '<span>hello</span>&#8212;[code]',
    1715             ),
    1716             array(
    1717                 '<span>hello[code]---</span>',
    1718                 '<span>hello[code]---</span>',
    1719             ),
    1720             array(
    1721                 '[code]hello<span>---</span>',
    1722                 '[code]hello<span>---</span>',
    1723             ),
    1724             array(
    1725                 '[code]hello</span>---</span>',
    1726                 '[code]hello</span>---</span>',
     1692                '<span><code>hello</code>---</span>',
     1693                '<span><code>hello</code>&#8212;</span>',
     1694            ),
     1695            array(
     1696                '<code>hello</code>world<span>---</span>',
     1697                '<code>hello</code>world<span>&#8212;</span>',
     1698            ),
     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(
     1724            array(
     1725                '[a]a--b[audio]---[/audio]a--b[/a]',
     1726                '[a]a&#8211;b[audio]---[/audio]a&#8211;b[/a]',
     1727            ),
     1728            array(
     1729                '[code ...]...[/code]', // code is not a registered shortcode.
     1730                '[code &#8230;]&#8230;[/code]',
     1731            ),
     1732            array(
     1733                '[hello ...]...[/hello]', // hello is not a registered shortcode.
     1734                '[hello &#8230;]&#8230;[/hello]',
     1735            ),
     1736            array(
     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;',
     1739            ),
     1740            array(
     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.
     1743            ),
     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>',
    17271771            ),
    17281772        );
Note: See TracChangeset for help on using the changeset viewer.