Make WordPress Core

Opened 7 years ago

Last modified 3 months ago

#47279 new defect (bug)

$post object passed to clean_post_cache action can contain outdated values

Reported by: tabrisrp's profile tabrisrp Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version: 2.5
Component: Posts, Post Types Keywords: has-test-info needs-docs
Focuses: docs Cc:

Description

This occurs when publishing or deleting a post.

In the clean_post_cache() function, get_post( $post ) is called and assigned to $post.

At that moment, the value of the $post parameter post_status = draft if publishing, publish if deleting the post.

There is then a call to wp_cache_delete( $post->ID, 'post_meta' );, which correctly updates the value of post_status, if you perform another get_post() right after.

But, the $post object is then passed to the action clean_post_cache, with the outdated values instead.

So if someone hooks a function on clean_post_cache, and uses the $post object passed, it's going to receive incorrect values compared to what would be expected. But if you perform a get_post() inside that function, you will get the correct values.

I only tested this with the post_status parameter, but this might be affecting others too.

I would expect that the $post object passed to the clean_post_cache action contains up-to-date values.

Change History (4)

#1 @SergeyBiryukov
7 years ago

  • Keywords needs-patch needs-unit-tests added
  • Milestone changed from Awaiting Review to Future Release

#2 @SirLouen
3 months ago

  • Keywords good-first-bug has-test-info needs-testing added; needs-patch removed

Inspecting the code, I can see that this could still be happening.

If anyone wants to go for a patch for this, please submit a detailed reproduction report before submitting a patch (Use the following format).

#3 follow-up: @peterwilsoncc
3 months ago

  • Focuses docs added
  • Version set to 2.5

Yeah, I can see how this would happen & it seems like it was a mistake to pass the $post parameter to the action. Unfortunately, it's a mistake made in version 2.5 so it's too late to fix it now.

I think this is a documentation fix rather than a code fix. Changing the hook to do_action( 'clean_post_cache', $post->ID, get_post( $post->ID ) ); would trigger a database call for the post to reprime the cache.

There are multiple instances in the code base where the post cache is cleared in a loop. In these cases, that would trigger a database call for each of the posts being cleared. ref 1, ref 2, there are others.

It's also pretty risky to start priming the cache in clean_post_cache() as it could affect post updates with order of operations issues.

#4 in reply to: ↑ 3 @SirLouen
3 months ago

  • Keywords needs-docs added; needs-unit-tests good-first-bug needs-testing removed

Replying to peterwilsoncc:

I think this is a documentation fix rather than a code fix. Changing the hook to do_action( 'clean_post_cache', $post->ID, get_post( $post->ID ) ); would trigger a database call for the post to reprime the cache.

Ok, I need to dig a little further into this, but let's move this with some docs.

Note: See TracTickets for help on using tickets.