Make WordPress Core

Opened 14 months ago

Closed 14 months ago

Last modified 13 months ago

#62370 closed defect (bug) (duplicate)

Fatal error in convert_smilies() due to count() receiving non-countable value

Reported by: mcqueen22's profile mcqueen22 Owned by:
Milestone: Priority: normal
Severity: normal Version: 6.6.2
Component: Formatting Keywords: has-patch needs-testing
Focuses: php-compatibility Cc:

Description

Hi,

I have identified a recurring error in the convert_smilies() function located in the wp-includes/formatting.php file. The error I encountered is as follows:

Fatal error: Uncaught Error: count(): Argument #1 ($value) must be of type Countable|array, false given

This occurs on line 3495 of the formatting.php file, where the count() function attempts to count a value $textarr that may be false. After investigating, I discovered that preg_split() in the convert_smilies() function returns false under certain circumstances, causing this error.

I made a modification to prevent this issue by verifying that $textarr is an array before calling count(). The modified code is as follows:

#!php if ( is_array( $textarr ) ) { $stop = count( $textarr ); } else { $stop = 0; }

This modification ensures that count() only receives a valid value, avoiding the fatal error. I would appreciate it if you could review this solution and consider including a similar change in a future version of WordPress to prevent other users from experiencing this problem.

My PHP version is 8.3.

I wait tour news. Thanks

Change History (4)

#1 @azaozz
14 months ago

  • Milestone Awaiting Review deleted
  • Resolution set to duplicate
  • Status changed from new to closed

Thanks for the ticket and the patch. Seems a duplicate of #51019 (that will be fixed in 6.8). Feel free to reopen if it's not.

Last edited 14 months ago by azaozz (previous) (diff)

#2 @mcqueen22
14 months ago

Comment to Add to Ticket #51019 on WordPress Trac

Possible Solution for the Issue with convert_smilies()

Hi, I have encountered the same error described in ticket #51019:

Fatal error: Uncaught Error: count(): Argument #1 ($value) must be of type Countable|array, false given

This happens in the formatting.php file, specifically in the convert_smilies() function, where preg_split() returns false and count() tries to handle it, resulting in a fatal error.

Implemented Solution
To prevent this issue, I modified the convert_smilies() function by adding a verification to ensure that count() only processes valid values.

Below is the complete modified version of the convert_smilies() function:

function convert_smilies( $text ) {
    global $wp_smiliessearch;
    $output = '';

    // Verify if smilies are enabled and if the smilies search pattern is defined.
    if ( get_option( 'use_smilies' ) && ! empty( $wp_smiliessearch ) ) {
        // Split the text into elements using preg_split.
        $textarr = preg_split( '/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // Capture the tags as well as in between.

        // Check if $textarr is an array before continuing.
        if ( is_array( $textarr ) ) {
            $stop = count( $textarr ); // Count elements for the loop.

            // Ignore processing of certain tags.
            $tags_to_ignore       = 'code|pre|style|script|textarea';
            $ignore_block_element = '';

            // Iterate over each part of the text.
            for ( $i = 0; $i < $stop; $i++ ) {
                $content = $textarr[ $i ];

                // If we are in an ignore block, wait until we find its closing tag.
                if ( '' === $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')[^>]*>/', $content, $matches ) ) {
                    $ignore_block_element = $matches[1];
                }

                // If it's not a tag and not in an ignore block.
                if ( '' === $ignore_block_element && strlen( $content ) > 0 && '<' !== $content[0] ) {
                    $content = preg_replace_callback( $wp_smiliessearch, 'translate_smiley', $content );
                }

                // Did we exit the ignore block?
                if ( '' !== $ignore_block_element && '</' . $ignore_block_element . '>' === $content ) {
                    $ignore_block_element = '';
                }

                $output .= $content;
            }
        } else {
            // If $textarr is not an array, return the original text without changes.
            $output = $text;
        }
    } else {
        // Return the original text if smilies are not used.
        $output = $text;
    }

    return $output;
}

Description of the Change:

  • Check $textarr: Added a check to ensure $textarr is an array before attempting to use count():
    if ( is_array( $textarr ) ) {
        $stop = count( $textarr );
    } else {
        $stop = 0;
    }
    
  • This ensures that count() only receives countable values, preventing the fatal error.

Additional Context
This issue was encountered while using the Woodmart theme in combination with some WooCommerce features. The the_content() function triggered convert_smilies(), which is where the error occurred.

I hope this solution helps improve the functionality of convert_smilies() and prevents similar errors for other users. I am available to test patches or provide any additional information if needed.

Regards

@SergeyBiryukov commented on PR #7774:


13 months ago
#4

Thanks for the PR! Merged in r59515.

Note: See TracTickets for help on using tickets.