🔞 ADULT: Changeset/ - Complete Album!

Changeset 59515


Ignore:
Timestamp:
12/14/2024 11:51:09 PM (13 months ago)
Author:
SergeyBiryukov
Message:

Formatting: Check the result of preg_split() in convert_smilies().

This aims to avoid a fatal error from count() when preg_split() fails on large input.

Includes:

  • Optimizing the regular expression used to split the input by tags to avoid unlimited backtracking for better performance.
  • Adjusting the function logic for better readability.

Follow-up to [340], [4380], [26191].

Props podpirate, nathkrill, rajinsharwar, dmsnell, bjorsch, q0rban, audrasjb, rupw, Ov3rfly, jorbin, nhrrob, chaion07, mcqueen22, azaozz, narenin, roybellingan, SergeyBiryukov.
See #51019.

Location:
trunk
Files:
2 edited

Legend:

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

    r59333 r59515  
    34743474function convert_smilies( $text ) {
    34753475    global $wp_smiliessearch;
     3476
     3477    if ( ! get_option( 'use_smilies' ) || empty( $wp_smiliessearch ) ) {
     3478        // Return default text.
     3479        return $text;
     3480    }
     3481
     3482    // HTML loop taken from texturize function, could possible be consolidated.
     3483    $textarr = preg_split( '/(<[^>]*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // Capture the tags as well as in between.
     3484
     3485    if ( false === $textarr ) {
     3486        // Return default text.
     3487        return $text;
     3488    }
     3489
     3490    // Loop stuff.
     3491    $stop   = count( $textarr );
    34763492    $output = '';
    3477     if ( get_option( 'use_smilies' ) && ! empty( $wp_smiliessearch ) ) {
    3478         // HTML loop taken from texturize function, could possible be consolidated.
    3479         $textarr = preg_split( '/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // Capture the tags as well as in between.
    3480         $stop    = count( $textarr ); // Loop stuff.
    3481 
    3482         // Ignore processing of specific tags.
    3483         $tags_to_ignore       = 'code|pre|style|script|textarea';
    3484         $ignore_block_element = '';
    3485 
    3486         for ( $i = 0; $i < $stop; $i++ ) {
    3487             $content = $textarr[ $i ];
    3488 
    3489             // If we're in an ignore block, wait until we find its closing tag.
    3490             if ( '' === $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')[^>]*>/', $content, $matches ) ) {
    3491                 $ignore_block_element = $matches[1];
    3492             }
    3493 
    3494             // If it's not a tag and not in ignore block.
    3495             if ( '' === $ignore_block_element && strlen( $content ) > 0 && '<' !== $content[0] ) {
    3496                 $content = preg_replace_callback( $wp_smiliessearch, 'translate_smiley', $content );
    3497             }