Commit 6a8ff2b2dcf for woocommerce
commit 6a8ff2b2dcf8a873da3e768d19e6eb498a650022
Author: Kamal Hosen <kamalhosen8920@gmail.com>
Date: Wed Aug 12 15:55:09 2026 +0600
Guard against malformed data from `woocommerce_variation_prices` filter (#66875)
* Add guard against malformed data from woocommerce_variation_prices filter
When the 'woocommerce_variation_prices' filter returns malformed data
(non-array or missing required keys), downstream code in
WC_Product_Variable::get_variation_prices() can fatal with TypeError
on array_map() or foreach.
This adds validate_price_data_entry() to validate the structure and
falls back to the original unfiltered price data when the filter
returns unexpected data.
Fixes #66851
* Use deprecation cycle for malformed woocommerce_variation_prices data
* Add unit tests for malformed woocommerce_variation_prices deprecation
* Simplify tests for malformed variation prices filter
* Expect deprecation warning in malformed prices test
---------
Co-authored-by: Vladimir Reznichenko <kalessil@gmail.com>
diff --git a/plugins/woocommerce/changelog/fix-66851-malformed-variation-prices b/plugins/woocommerce/changelog/fix-66851-malformed-variation-prices
new file mode 100644
index 00000000000..50998f7cc32
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-66851-malformed-variation-prices
@@ -0,0 +1,3 @@
+Significance: minor
+Type: fix
+Comment: Add guard against malformed data from woocommerce_variation_prices filter
diff --git a/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php b/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php
index 75b90f62d72..8a13ac2fa8e 100644
--- a/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php
+++ b/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php
@@ -573,9 +573,23 @@ class WC_Product_Variable_Data_Store_CPT extends WC_Product_Data_Store_CPT imple
* @param bool $for_display Whether prices are being retrieved for display.
*/
$this->prices_array[ $price_hash ] = apply_filters( 'woocommerce_variation_prices', $transient_cached_prices_array[ $price_hash ], $product, $for_display );
+ if ( $this->prices_array[ $price_hash ] !== $transient_cached_prices_array[ $price_hash ] && ! $this->validate_prices_data( array( $price_hash => $this->prices_array[ $price_hash ] ), $transient_version ) ) {
+ wc_doing_it_wrong(
+ __METHOD__,
+ __( '`woocommerce_variation_prices` returned an unsupported data format. The value is currently used as-is but will be ignored in a future release. Ensure your callback returns the expected array structure.', 'woocommerce' ),
+ '11.1'
+ );
+ }
+
if ( null !== $opposite_price_hash && $opposite_price_hash !== $price_hash ) {
- // phpcs:ignore WooCommerce.Commenting.CommentHooks
$this->prices_array[ $opposite_price_hash ] = apply_filters( 'woocommerce_variation_prices', $transient_cached_prices_array[ $opposite_price_hash ], $product, ! $for_display );
+ if ( $this->prices_array[ $opposite_price_hash ] !== $transient_cached_prices_array[ $opposite_price_hash ] && ! $this->validate_prices_data( array( $opposite_price_hash => $this->prices_array[ $opposite_price_hash ] ), $transient_version ) ) {
+ wc_doing_it_wrong(
+ __METHOD__,
+ __( '`woocommerce_variation_prices` returned an unsupported data format. The value is currently used as-is but will be ignored in a future release. Ensure your callback returns the expected array structure.', 'woocommerce' ),
+ '11.1'
+ );
+ }
}
}
return $this->prices_array[ $price_hash ];
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 d1fbef9739d..17ea8395de8 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
@@ -424,6 +424,8 @@ class WC_Product_Variable_Test extends \WC_Unit_Test_Case {
$bad_filter = static fn() => $malformed_value;
add_filter( 'woocommerce_variation_prices', $bad_filter );
+ $this->setExpectedIncorrectUsage( 'WC_Product_Variable_Data_Store_CPT::read_price_data' );
+
try {
$prices = $product->get_variation_prices();
$this->assertSame( $malformed_value, $prices );