Commit 3fb02078e0a for woocommerce

commit 3fb02078e0a0f7b85bcf1d97d59cd8f91420e675
Author: Vladimir Reznichenko <kalessil@gmail.com>
Date:   Thu Jul 23 06:00:07 2026 +0200

    [Performance] Address edge-case concerns reported by an AI after merging #66675. (#66810)

diff --git a/plugins/woocommerce/includes/class-wc-product-variable.php b/plugins/woocommerce/includes/class-wc-product-variable.php
index 2dd266c1d73..cba96f39486 100644
--- a/plugins/woocommerce/includes/class-wc-product-variable.php
+++ b/plugins/woocommerce/includes/class-wc-product-variable.php
@@ -111,6 +111,9 @@ class WC_Product_Variable extends WC_Product {
 	public function get_variation_prices( $for_display = false ) {
 		/** @var array<string,array<int,float>> $prices */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
 		$prices = $this->data_store->read_price_data( $this, $for_display );
+		if ( ! is_array( $prices ) ) {
+			return $prices;
+		}

 		// Performance note: loose != compares key/value pairs regardless of order, so a re-sort is only triggered when prices actually change.
 		$cache_key = $for_display ? 'for_display:1' : 'for_display:0';
diff --git a/plugins/woocommerce/tests/php/includes/class-wc-product-variable-test.php b/plugins/woocommerce/tests/php/includes/class-wc-product-variable-test.php
index d1895097255..d1fbef9739d 100644
--- a/plugins/woocommerce/tests/php/includes/class-wc-product-variable-test.php
+++ b/plugins/woocommerce/tests/php/includes/class-wc-product-variable-test.php
@@ -408,6 +408,45 @@ class WC_Product_Variable_Test extends \WC_Unit_Test_Case {
 		$product->delete( true );
 	}

+	/**
+	 * @testdox get_variation_prices returns a valid array structure when the woocommerce_variation_prices filter returns malformed data (null or false), restoring the pre-refactor foreach behaviour that tolerated non-array filter output.
+	 * @dataProvider provider_malformed_variation_prices_filter_values
+	 *
+	 * @param mixed $malformed_value The malformed value for returning via woocommerce_get_variation_prices_hash filter.
+	 */
+	public function test_get_variation_prices_tolerates_malformed_filter_output( $malformed_value ): void {
+		$product = WC_Helper_Product::create_variation_product();
+
+		// Bust the transient so read_price_data() always reaches the woocommerce_variation_prices filter.
+		$invalidate_cache = static fn( array $hash ) => array( ...$hash, wp_rand() );
+		add_filter( 'woocommerce_get_variation_prices_hash', $invalidate_cache );
+
+		$bad_filter = static fn() => $malformed_value;
+		add_filter( 'woocommerce_variation_prices', $bad_filter );
+
+		try {
+			$prices = $product->get_variation_prices();
+			$this->assertSame( $malformed_value, $prices );
+		} finally {
+			remove_filter( 'woocommerce_variation_prices', $bad_filter );
+			remove_filter( 'woocommerce_get_variation_prices_hash', $invalidate_cache );
+		}
+
+		$product->delete( true );
+	}
+
+	/**
+	 * @return array<string,array>
+	 */
+	public function provider_malformed_variation_prices_filter_values(): array {
+		return array(
+			'null'   => array( null ),
+			'false'  => array( false ),
+			'string' => array( 'bad_return' ),
+			'object' => array( new stdClass() ),
+		);
+	}
+
 	/**
 	 * Create a real image attachment that passes `wp_attachment_is_image()`.
 	 *