WordPress.org

Make WordPress Core

Changeset 18952


Ignore:
Timestamp:
10/12/11 16:50:30 (3 years ago)
Author:
ryan
Message:

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

Location:
trunk/wp-includes
Files:
2 edited

Legend:

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

    r18877 r18952  
    233233 * @return string The filtered content. 
    234234 */ 
    235 function shortcode_unautop($pee) { 
     235function shortcode_unautop( $pee ) { 
    236236    global $shortcode_tags; 
    237237 
    238     if ( !empty($shortcode_tags) && is_array($shortcode_tags) ) { 
    239         $tagnames = array_keys($shortcode_tags); 
    240         $tagregexp = join( '|', array_map('preg_quote', $tagnames) ); 
    241         $pee = preg_replace('/<p>\\s*?(\\[(' . $tagregexp . ')\\b.*?\\/?\\](?:.+?\\[\\/\\2\\])?)\\s*<\\/p>/s', '$1', $pee); 
    242     } 
    243  
    244     return $pee; 
     238    if ( empty( $shortcode_tags ) || !is_array( $shortcode_tags ) ) { 
     239        return $pee; 
     240    } 
     241 
     242    $tagregexp = join( '|', array_map( 'preg_quote', array_keys( $shortcode_tags ) ) ); 
     243 
     244    $pattern = 
     245          '/' 
     246        . '<p>'                              // Opening paragraph 
     247        . '\\s*+'                            // Optional leading whitespace 
     248        . '('                                // 1: The shortcode 
     249        .     '\\['                          // Opening bracket 
     250        .     "($tagregexp)"                 // 2: Shortcode name 
     251        .     '\\b'                          // Word boundary 
     252                                             // Unroll the loop: Inside the opening shortcode tag 
     253        .     '[^\\]\\/]*'                   // Not a closing bracket or forward slash 
     254        .     '(?:' 
     255        .         '\\/(?!\\])'               // A forward slash not followed by a closing bracket 
     256        .         '[^\\]\\/]*'               // Not a closing bracket or forward slash 
     257        .     ')*?' 
     258        .     '(?:' 
     259        .         '\\/\\]'                   // Self closing tag and closing bracket 
     260        .     '|' 
     261        .         '\\]'                      // Closing bracket 
     262        .         '(?:'                      // Unroll the loop: Optionally, anything between the opening and closing shortcode tags 
     263        .             '[^\\[]*+'             // Not an opening bracket 
     264        .             '(?:' 
     265        .                 '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag 
     266        .                 '[^\\[]*+'         // Not an opening bracket 
     267        .             ')*+' 
     268        .             '\\[\\/\\2\\]'         // Closing shortcode tag 
     269        .         ')?' 
     270        .     ')' 
     271        . ')' 
     272        . '\\s*+'                            // optional trailing whitespace 
     273        . '<\\/p>'                           // closing paragraph 
     274        . '/s'; 
     275 
     276    return preg_replace( $pattern, '$1', $pee ); 
    245277} 
    246278 
  • 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.