Make WordPress Core

Opened 10 months ago

Closed 9 months ago

Last modified 9 months ago

#60800 closed defect (bug) (fixed)

Twenty Twenty-One: prevent PHP 8 fatal error from non-string in $tags_list

Reported by: josephscott's profile josephscott Owned by: sergeybiryukov's profile SergeyBiryukov
Milestone: 6.6 Priority: normal
Severity: normal Version:
Component: Bundled Theme Keywords: good-first-bug has-patch needs-testing 2nd-opinion
Focuses: Cc:

Description

In /inc/template-tags.php there is a call to get_the_tag_list() - https://themes.trac.wordpress.org/browser/twentytwentyone/2.1/inc/template-tags.php#L154

The only check on the return value is an if condition. The problem is that a few lines down ( 159 ) it is required to be a string. But the get_the_tag_list() function is documented as being able to return string|false|WP_Error - https://developer.wordpress.org/reference/functions/get_the_tag_list/

When a WP_Error object is returned and used in the string context of the printf() a fatal error happens in PHP 8.1:

PHP Fatal error:  Uncaught Error: Object of class WP_Error could not be converted to string in twentytwentyone/inc/template-tags.php:159

The if condition should be updated to ensure that the printf() only gets called if the return value of get_the_tag_list() is indeed a string. Something like:

if ( is_string( $tags_list ) ) {

Change History (8)

#1 @poena
10 months ago

  • Keywords needs-patch added
  • Milestone changed from Awaiting Review to 6.6

#2 @sabernhardt
10 months ago

  • Keywords good-first-bug added
  • Summary changed from Fix Potential PHP 8 Fatal Error in Twenty Twenty-One to Twenty Twenty-One: prevent PHP 8 fatal error from non-string in $tags_list

Thanks for the report!

Other default themes have checked for WP_Error with this condition:
if ( $tags_list && ! is_wp_error( $tags_list ) )

Both lines 113 and 155 would need updating in template-tags.php.

#3 @sabernhardt
10 months ago

Every bundled theme before Twenty Twenty-One included the ! is_wp_error() condition when using get_the_tag_list() (Twenty Fourteen and Twenty Twenty have the_tags() instead).

This ticket was mentioned in PR #6290 on WordPress/wordpress-develop by nirav7707.


10 months ago
#4

  • Keywords has-patch added; needs-patch removed

Trac ticket

Implemented validation to ensure that the variable holding the return value of the function get_the_tag_list is not a WP_Error object.

#5 @devsahadat
10 months ago

  • Keywords changes-requested added

To address the issue encountered in the twenty_twenty_one_entry_meta_footer() function within /inc/template-tags.php, it's imperative to ensure that the $tags_list variable holds a string value before being passed to the printf() function. This adjustment is crucial for maintaining compatibility, particularly with PHP 8.1.

Below is the proposed modification to the code:

$tags_list = get_the_tag_list( '', wp_get_list_item_separator() );
if ( is_string( $tags_list ) ) { // Adding this check ensures $tags_list is a string
    if ( $tags_list ) {
        printf(
            /* translators: %s: List of tags. */
            '<span class="tags-links">' . esc_html__( 'Tagged %s', 'twentytwentyone' ) . '</span>',
            $tags_list // phpcs:ignore WordPress.Security.EscapeOutput
        );
    }
}

By implementing this adjustment, the printf() function will only execute if $tags_list is indeed a string. Consequently, this preemptive validation mitigates the occurrence of fatal errors, specifically those stemming from $tags_list being a WP_Error object under PHP 8.1.

#6 @sabernhardt
10 months ago

  • Keywords needs-testing 2nd-opinion added; changes-requested removed

get_the_tag_list() returns either a string, false or the WP_Error. Twenty Twenty-One should only need to add a condition for the error (as PR 6290 does).

The condition if ( $tags_list && is_string( $tags_list ) ) is another possibility. If that is preferred, however, it would belong in nine themes to be consistent.

#7 @SergeyBiryukov
9 months ago

  • Owner set to SergeyBiryukov
  • Resolution set to fixed
  • Status changed from new to closed

In 57991:

Twenty Twenty-One: Check for WP_Error before outputting get_the_tag_list().

This prevents a fatal error on PHP 8 and brings consistency with the other bundled themes.

Follow-up to [47886].

Props josephscott, sabernhardt, poena, nirav7707, devsahadat.
Fixes #60800.

@SergeyBiryukov commented on PR #6290:


9 months ago
#8

Thanks for the PR! Merged in r57991.

Note: See TracTickets for help on using tickets.