From b9304148f17278dbe9a4199a1143b083188f0d61 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Thu, 10 Nov 2022 02:59:56 +0000 Subject: [PATCH] Canonical: Protect against error for term not exists queries. Prevent term `NOT EXISTS` queries causing `redirect_canonical()` to throw a fatal error in PHP 8 and above, or a warning in earlier versions. This ensures the `tax_query`'s `terms` property both exists and is countable before attempting to count it. Props codesdnc, SergeyBiryukov, kadamwhite, costdev, miguelaxcar. Fixes #55955. git-svn-id: https://develop.svn.wordpress.org/trunk@54785 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/canonical.php | 4 +++- tests/phpunit/tests/canonical.php | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/canonical.php b/src/wp-includes/canonical.php index 9404ed6ea5..5e8efb0bae 100644 --- a/src/wp-includes/canonical.php +++ b/src/wp-includes/canonical.php @@ -331,7 +331,9 @@ function redirect_canonical( $requested_url = null, $do_redirect = true ) { $term_count = 0; foreach ( $wp_query->tax_query->queried_terms as $tax_query ) { - $term_count += count( $tax_query['terms'] ); + if ( isset( $tax_query['terms'] ) && is_countable( $tax_query['terms'] ) ) { + $term_count += count( $tax_query['terms'] ); + } } $obj = $wp_query->get_queried_object(); diff --git a/tests/phpunit/tests/canonical.php b/tests/phpunit/tests/canonical.php index 63e5c4078b..6d16402112 100644 --- a/tests/phpunit/tests/canonical.php +++ b/tests/phpunit/tests/canonical.php @@ -375,4 +375,31 @@ class Tests_Canonical extends WP_Canonical_UnitTestCase { delete_option( 'page_on_front' ); } + + /** + * Ensure NOT EXISTS queries do not trigger not-countable or undefined array key errors. + * + * @ticket 55955 + */ + public function test_feed_canonical_with_not_exists_query() { + // Set a NOT EXISTS tax_query on the global query. + $global_query = $GLOBALS['wp_query']; + $GLOBALS['wp_query'] = new WP_Query( + array( + 'post_type' => 'post', + 'tax_query' => array( + array( + 'taxonomy' => 'post_format', + 'operator' => 'NOT EXISTS', + ), + ), + ) + ); + + $url = redirect_canonical( get_term_feed_link( self::$terms['/category/parent/'] ), false ); + // Restore original global. + $GLOBALS['wp_query'] = $global_query; + + $this->assertNull( $url ); + } }