WordPress.org

Make WordPress Core


Ignore:
Timestamp:
10/12/2011 04:50:30 PM (10 years ago)
Author:
ryan
Message:

Avoid preg backtrack limit errors with large posts when processing shortcodes. Props mdawaffe. fixes #15600

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/shortcodes.php

    r18639 r18952  
    149149
    150150    $pattern = get_shortcode_regex();
    151     return preg_replace_callback('/'.$pattern.'/s', 'do_shortcode_tag', $content);
     151    return preg_replace_callback( "/$pattern/s", 'do_shortcode_tag', $content );
    152152}
    153153
     
    160160 * The regular expression contains 6 different sub matches to help with parsing.
    161161 *
    162  * 1/6 - An extra [ or ] to allow for escaping shortcodes with double [[]]
     162 * 1 - An extra [ to allow for escaping shortcodes with double [[]]
    163163 * 2 - The shortcode name
    164164 * 3 - The shortcode argument list
    165165 * 4 - The self closing /
    166166 * 5 - The content of a shortcode when it wraps some content.
     167 * 6 - An extra ] to allow for escaping shortcodes with double [[]]
    167168 *
    168169 * @since 2.5
     
    176177    $tagregexp = join( '|', array_map('preg_quote', $tagnames) );
    177178
    178     // WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcodes()
    179     return '(.?)\[('.$tagregexp.')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)';
     179    // WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcode_tag()
     180    return
     181          '\\['                              // Opening bracket
     182        . '(\\[?)'                           // 1: Optional second opening bracket for escaping shortcodes: [[tag]]
     183        . "($tagregexp)"                     // 2: Shortcode name
     184        . '\\b'                              // Word boundary
     185        . '('                                // 3: Unroll the loop: Inside the opening shortcode tag
     186        .     '[^\\]\\/]*'                   // Not a closing bracket or forward slash
     187        .     '(?:'
     188        .         '\\/(?!\\])'               // A forward slash not followed by a closing bracket
     189        .         '[^\\]\\/]*'               // Not a closing bracket or forward slash
     190        .     ')*?'
     191        . ')'
     192        . '(?:'
     193        .     '(\\/)'                        // 4: Self closing tag ...
     194        .     '\\]'                          // ... and closing bracket
     195        . '|'
     196        .     '\\]'                          // Closing bracket
     197        .     '(?:'
     198        .         '('                        // 5: Unroll the loop: Optionally, anything between the opening and closing shortcode tags
     199        .             '[^\\[]*+'             // Not an opening bracket
     200        .             '(?:'
     201        .                 '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag
     202        .                 '[^\\[]*+'         // Not an opening bracket
     203        .             ')*+'
     204        .         ')'
     205        .         '\\[\\/\\2\\]'             // Closing shortcode tag
     206        .     ')?'
     207        . ')'
     208        . '(\\]?)';                          // 6: Optional second closing brocket for escaping shortcodes: [[tag]]
    180209}
    181210
     
    291320    $pattern = get_shortcode_regex();
    292321
    293     return preg_replace('/'.$pattern.'/s', '$1$6', $content);
     322    return preg_replace_callback( "/$pattern/s", 'strip_shortcode_tag', $content );
     323}
     324
     325function strip_shortcode_tag( $m ) {
     326    // allow [[foo]] syntax for escaping a tag
     327    if ( $m[1] == '[' && $m[6] == ']' ) {
     328        return substr($m[0], 1, -1);
     329    }
     330
     331    return $m[1] . $m[6];
    294332}
    295333
Note: See TracChangeset for help on using the changeset viewer.