Make WordPress Core

Opened 5 weeks ago

Closed 3 weeks ago

#66091 closed defect (bug) (fixed)

Check cache return value in metadata_exists(), get_metadata_raw(), and update_meta_cache()

Reported by: josephscott Owned by: peterwilsoncc
Priority: normal Milestone: 7.2
Component: Options, Meta APIs Version:
Severity: normal Keywords: has-patch has-unit-tests commit
Cc: Focuses:

Description

The meta functions read the {$meta_type}_meta cache group and only check the return value for falsiness before using it as an array:

<?php
$meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' );

if ( ! $meta_cache ) {
        $meta_cache = update_meta_cache( $meta_type, array( $object_id ) );
        $meta_cache = $meta_cache[ $object_id ];
}

if ( isset( $meta_cache[ $meta_key ] ) ) {

If the cache returns anything other than an array, isset() on an object is a fatal error, and the other types silently produce wrong results.

The same thing happens in get_metadata_raw() ( ​GH ) and metadata_exists() ( ​GH ). Both fall back to update_meta_cache(), which reads the same group through wp_cache_get_multiple() and only checks for false ( ​GH ), so it hands the unusable value straight back.

A non-array cached value should be treated as a cache miss in all three places. This is another case for #66005, where WP core could use a validating cache function.

This also speaks to the broader issue of making sure return values are correctly checked before making use of them.

I have a PR to address this.

Change History (6)

This ticket was mentioned in ​PR #13481 on ​WordPress/wordpress-develop by ​@josephscott.


5 weeks ago
#1

  • Keywords has-patch has-unit-tests added

…d update_meta_cache()

https://core.trac.wordpress.org/ticket/66091

AI assistance: Yes
Tool(s): Claude Code
Model(s): Fable 5.1
Used for: talking over the general issue, exploring options - it wrote all of the tests.

#2 @westonruter
5 weeks ago

  • Milestone Awaiting Review → 7.2

#3 @jonsurrell
4 weeks ago

  • Keywords commit added

#4 @peterwilsoncc
3 weeks ago

  • Keywords commit removed

I've put a couple of changes requests on the PR so am removing the commit keyword. The suggestions are super minor, mainly coding standards and the inevitable naming things discussion.

#5 @peterwilsoncc
3 weeks ago

  • Keywords commit added

#6 @peterwilsoncc
3 weeks ago

  • Owner set to peterwilsoncc
  • Resolution → fixed
  • Status new → closed

In 63958:

Options, Meta APIs: Ensure meta cache is an array before use.

In get_metadata_raw() and metadata_exists() ensure that cached data is of a valid form (ie, an array) before use. This prevents PHP errors of a third party has set the cache directly using a non array value.

Each of these functions now treat invalid cache forms as a cache miss. Invalid cache entries are deleted in update_meta_cache() if they are not an array.

Props josephscott, jonsurrell, westonruter.
Fixes #66091.

Note: See TracTickets for help on using tickets.