Fix: Multiple issues related to MySQL having ANSI_QUOTES enabled in Product Filters (#51316)

* Fix: Use prepared statements for stock status filtering

This commit addresses an issue where the "Filter by stock" block fails when used with MySQL that has ANSI_QUOTES enabled. The problem was caused
by the use of double quotes in the SQL query.

Key changes:
1. Replace direct string concatenation with wpdb->prepare()
2. Use placeholders for stock status values in the IN clause
3. Validate stock statuses against known options before querying

This fix ensures compatibility with different MySQL configurations and improves
the overall security of the query by preventing SQL injection vulnerabilities.

* Add changefile(s) from automation for the following project(s): woocommerce

* Fix lint errors

* Fix lint issue

* Fix: Use single quotes for attribute taxonomy names in SQL query

- Addresses issue with Filter by Attribute block failing with ANSI_QUOTES enabled
- Prevents "Unknown column" errors for attribute names in SQL queries

* Fix: Use single quotes for SQL IN clauses

This commit addresses an issue where the Filter by Stock block fails when
the database has ANSI_QUOTES enabled. The problem was caused by the use of
double quotes in SQL IN clauses, which are treated as identifiers when
ANSI_QUOTES is enabled.

The fix involves replacing double quotes with single quotes in the following files:
1. plugins/woocommerce/src/Blocks/QueryFilters.php
2. plugins/woocommerce/src/StoreApi/Utilities/ProductQuery.php

This change ensures compatibility with databases that have ANSI_QUOTES
enabled, while maintaining the existing functionality for other configurations.

* Add changefile(s) from automation for the following project(s): woocommerce

---------

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
Manish Menaria 2024-10-18 09:46:32 +05:30 committed by GitHub
parent 8ad73e6b11
commit b4605c75e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 11 additions and 6 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: fix
Fix: Multiple issues related to MySQL having `ANSI_QUOTES` enabled in Product Filters

View File

@ -209,7 +209,7 @@ final class QueryFilters {
} }
$args['join'] = $this->append_product_sorting_table_join( $args['join'] ); $args['join'] = $this->append_product_sorting_table_join( $args['join'] );
$args['where'] .= ' AND wc_product_meta_lookup.stock_status IN ("' . implode( '","', array_map( 'esc_sql', explode( ',', $wp_query->get( 'filter_stock_status' ) ) ) ) . '")'; $args['where'] .= ' AND wc_product_meta_lookup.stock_status IN (\'' . implode( '\',\'', array_map( 'esc_sql', explode( ',', $wp_query->get( 'filter_stock_status' ) ) ) ) . '\')';
return $args; return $args;
} }

View File

@ -359,7 +359,7 @@ class ProductQuery {
$skus[] = $wp_query->get( 'sku' ); $skus[] = $wp_query->get( 'sku' );
} }
$args['join'] = $this->append_product_sorting_table_join( $args['join'] ); $args['join'] = $this->append_product_sorting_table_join( $args['join'] );
$args['where'] .= ' AND wc_product_meta_lookup.sku IN ("' . implode( '","', array_map( 'esc_sql', $skus ) ) . '")'; $args['where'] .= ' AND wc_product_meta_lookup.sku IN (\'' . implode( '\',\'', array_map( 'esc_sql', $skus ) ) . '\')';
} }
if ( $wp_query->get( 'slug' ) ) { if ( $wp_query->get( 'slug' ) ) {
@ -375,10 +375,10 @@ class ProductQuery {
if ( $wp_query->get( 'stock_status' ) ) { if ( $wp_query->get( 'stock_status' ) ) {
$args['join'] = $this->append_product_sorting_table_join( $args['join'] ); $args['join'] = $this->append_product_sorting_table_join( $args['join'] );
$args['where'] .= ' AND wc_product_meta_lookup.stock_status IN ("' . implode( '","', array_map( 'esc_sql', $wp_query->get( 'stock_status' ) ) ) . '")'; $args['where'] .= ' AND wc_product_meta_lookup.stock_status IN (\'' . implode( '\',\'', array_map( 'esc_sql', $wp_query->get( 'stock_status' ) ) ) . '\')';
} elseif ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) { } elseif ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) {
$args['join'] = $this->append_product_sorting_table_join( $args['join'] ); $args['join'] = $this->append_product_sorting_table_join( $args['join'] );
$args['where'] .= ' AND wc_product_meta_lookup.stock_status NOT IN ("outofstock")'; $args['where'] .= ' AND wc_product_meta_lookup.stock_status NOT IN (\'outofstock\')';
} }
if ( $wp_query->get( 'min_price' ) || $wp_query->get( 'max_price' ) ) { if ( $wp_query->get( 'min_price' ) || $wp_query->get( 'max_price' ) ) {

View File

@ -153,8 +153,9 @@ class ProductQueryFilters {
}, },
$attributes $attributes
); );
$attributes_to_count_sql = 'AND term_taxonomy.taxonomy IN ("' . implode( '","', $attributes_to_count ) . '")'; $attributes_to_count_sql = 'AND term_taxonomy.taxonomy IN (\'' . implode( '\',\'', $attributes_to_count ) . '\')';
$attribute_count_sql = "
$attribute_count_sql = "
SELECT COUNT( DISTINCT posts.ID ) as term_count, terms.term_id as term_count_id SELECT COUNT( DISTINCT posts.ID ) as term_count, terms.term_id as term_count_id
FROM {$wpdb->posts} AS posts FROM {$wpdb->posts} AS posts
INNER JOIN {$wpdb->term_relationships} AS term_relationships ON posts.ID = term_relationships.object_id INNER JOIN {$wpdb->term_relationships} AS term_relationships ON posts.ID = term_relationships.object_id