Make WordPress Core

Opened 10 months ago

Closed 3 months ago

Last modified 3 months ago

#63263 closed defect (bug) (fixed)

check if exists before accessing object properties of $post->comment_count

Reported by: presskopp's profile Presskopp Owned by: westonruter's profile westonruter
Milestone: 6.9 Priority: normal
Severity: normal Version: 2.8
Component: General Keywords: needs-test-info has-screenshots has-patch has-unit-tests commit
Focuses: Cc:

Description

I got a

Warning: Attempt to read property "comment_count" on null in [...]\wp-includes\general-template.php on line 3352

let's check if the object exists and the property is not empty.

Original line:

if ( $show_post_comments_feed && ( comments_open() || pings_open() || $post->comment_count > 0 ) ) {

possible patch, something like:

if ( $show_post_comments_feed 
     && isset( $post ) 
     && $post instanceof WP_Post 
     && ( comments_open() || pings_open() || $post->comment_count > 0 ) 
) {

Attachments (2)

warning.png (178.3 KB) - added by Presskopp 9 months ago.
63263.patch (398 bytes) - added by johnjamesjacoby 3 months ago.

Download all attachments as: .zip

Change History (32)

#1 @abcd95
10 months ago

Hi, @Presskopp. Thanks for raising this.

Can you please sketch out the steps to reproduce the warning that you are observing?

Additional information, like the WP version or the theme version that you are using, will be helpful.

#2 @Presskopp
10 months ago

Hi @abcd95

I only get the warning when I provoke it. This happens during testing, not in productive operation. Nevertheless, I think the line should be changed.

You can provoke it by opening the Posts page and add a non existing page query like ?p=12345 to it.

Sorry, I should have mentioned it.

#3 @dilipbheda
10 months ago

@Presskopp I can't reproduce the issue. When I visit a page that doesn't exist, it shows a 404 page.

#4 @Presskopp
10 months ago

Did you define('WP_DEBUG', true); ?

#5 @dilipbheda
10 months ago

@Presskopp Yes

#6 @Presskopp
10 months ago

Interesting. I tried with Twenty Twenty-Five and Twenty Seventeen and I see the warning in both cases. Maybe it's because you have no posts at all or something!?

Please set permalinks to /%postname%/

Last edited 10 months ago by Presskopp (previous) (diff)

#7 @sabernhardt
10 months ago

  • Component changed from General to Feeds

(Line 3352 is inside the feed_links_extra() function)

#8 @Presskopp
9 months ago

FYI: there's a function get_comments_number( $post = 0 ), which could be helpful here. Also there are more instances of $post->comment_count in 3 more core files.

#9 @abcd95
9 months ago

  • Keywords needs-testing-info added

@Presskopp I followed everything you said, and I still don't see any warnings anywhere.

I did the following things -

Ensured I have enough posts in the system
Changed permalinks to /%postname%/
Accessed an invalid post ID (like localhost/blog/?p=12345 and even localhost/?p=12345)

However, I was only able to see the standard 404 Not Found page without any PHP warnings appearing. This matches the experience reported by @dilipbheda earlier.

Is there anything more to be done?

#10 @Presskopp
9 months ago

Weird. All I do after a fresh installation is

  • define('WP_DEBUG', true);
  • change permalinks to anything but 'Plain'
  • set a Posts page
  • open that Posts page and add a non existing page parameter like ?p=12345.
  • reload the page
  • see the warning

It makes no difference which theme is active (talking about standard themes)

Last edited 9 months ago by Presskopp (previous) (diff)

@Presskopp
9 months ago

#11 @Presskopp
9 months ago

  • Keywords has-screenshots added

#12 @Presskopp
9 months ago

As you can see on the screenshot, there's also an issue with the property "ID" using the Twenty Ten Theme. So we could open the scope of this ticket to a general check if objects and their properties exists, before assigning a value.

#13 @sabernhardt
9 months ago

  • Component changed from Feeds to General

#14 @indirabiswas27
9 months ago

I have carefully followed all the steps outlined, but I was only presented with the default 404 Not Found page, and no warnings appeared.

#15 @wordpressdotorg
9 months ago

  • Keywords needs-test-info added; needs-testing-info removed

#16 follow-up: @awetz583
5 months ago

I see this error as well on the custom classic/hybrid theme I'm working on.

To reproduce I:

  1. Go to a page that really does result in a 404 (like /nopenopenopenope/thisnomatch so it doesn't attempt to redirect to another post in the DB)
  2. The Page loads fine, but I see the PHP warning Attempt to read property "comment_count" on null

I think this is because there is now way to get a comment_count on a 404 page.
if ( $show_post_comments_feed && ( comments_open() || pings_open() || $post->comment_count > 0 ) ) { ...

Here is the error stack trace for WP 6.8.2:

wp-includes/general-template.php:3352

feed_links_extra()
wp-includes/class-wp-hook.php:324

do_action('wp_head')
wp-includes/general-template.php:3192

wp_head()
wp-content/themes/my-theme/header.php:7

#17 in reply to: ↑ 16 @awetz583
5 months ago

For now, I can add this to our theme as a workaround to remove the warning:

<?php
add_action( 'template_redirect', function() {
    if ( is_404() ) {
        add_filter( 'feed_links_extra_show_post_comments_feed', '__return_false' );
    }
});

Replying to awetz583:

I see this error as well on the custom classic/hybrid theme I'm working on.

To reproduce I:

  1. Go to a page that really does result in a 404 (like /nopenopenopenope/thisnomatch so it doesn't attempt to redirect to another post in the DB)
  2. The Page loads fine, but I see the PHP warning Attempt to read property "comment_count" on null

I think this is because there is now way to get a comment_count on a 404 page.
if ( $show_post_comments_feed && ( comments_open() || pings_open() || $post->comment_count > 0 ) ) { ...

Here is the error stack trace for WP 6.8.2:

wp-includes/general-template.php:3352

feed_links_extra()
wp-includes/class-wp-hook.php:324

do_action('wp_head')
wp-includes/general-template.php:3192

wp_head()
wp-content/themes/my-theme/header.php:7

#19 @westonruter
3 months ago

  • Milestone changed from Awaiting Review to 6.9
  • Owner set to westonruter
  • Status changed from new to assigned

#20 @johnjamesjacoby
3 months ago

This happens specifically when show_on_front is set, because the "Queried Object" is the Page ID of the Posts landing page, which makes is_singular() return true.

Patch incoming.

#21 follow-up: @westonruter
3 months ago

It wouldn't hurt to also include a $post instanceof WP_Post check as well, even though it is most likely that the global will have been set. There're no guarantees!

#22 in reply to: ↑ 21 @johnjamesjacoby
3 months ago

Replying to westonruter:

It wouldn't hurt to also include a $post instanceof WP_Post check as well, even though it is most likely that the global will have been set. There're no guarantees!

The surrounding code attempts to guarantee it here by mocking an empty WP_Post object:

https://core.trac.wordpress.org/browser/trunk/src/wp-includes/general-template.php#L3330

It just did not factor in the situation where a Singular queried object (home page) would simultaneously result in “no posts”. 🤣

#23 @westonruter
3 months ago

@johnjamesjacoby Here?

<?php
$id   = 0;
$post = get_post( $id );

That's not mocking an empty WP_Post object, is it? That seems to be just another way of doing $post = get_post() since an ID of 0 will result in the global $post being used. But if that global doesn't exist, then $post->comment_count would still issue a warning.

#24 @westonruter
3 months ago

  • Version set to 2.8

This code originates in r19094 to work around the fact that get_post() used to pass the first arg by reference (ref):

function &get_post(&$post, $output = OBJECT, $filter = 'raw')

The use of $post->comment_count originates in r10377 (19577d0).

This ticket was mentioned in PR #10401 on WordPress/wordpress-develop by @westonruter.


3 months ago
#25

  • Keywords has-patch has-unit-tests added

#26 @johnjamesjacoby
3 months ago

  • Keywords commit added

PR looks OK to me.

#27 @westonruter
3 months ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 61056:

General: Improve resilience of feed_links_extra() when global $post is not set.

This obtains the global post via get_queried_object() when is_singular().

Developed in https://github.com/WordPress/wordpress-develop/pull/10401

Props westonruter, johnjamesjacoby, Presskopp, abcd95, dilipbheda, sabernhardt, awetz583, indirabiswas27.
Fixes #63263.

#29 @westonruter
3 months ago

In 61058:

General: Add comment explaining use of queried object in feed_links_extra() instead of global $post.

Follow-up to [61056].

Props mukesh27, westonruter.
See #63263.

@westonruter commented on PR #10410:


3 months ago
#30

Committed in r61058.

Note: See TracTickets for help on using tickets.