diff --git a/assets/js/frontend/add-to-cart-variation.js b/assets/js/frontend/add-to-cart-variation.js index e4ee1241ad3..be56446a936 100644 --- a/assets/js/frontend/add-to-cart-variation.js +++ b/assets/js/frontend/add-to-cart-variation.js @@ -352,11 +352,19 @@ } if ( attr_val ) { - // Decode entities and add slashes. + // Decode entities. attr_val = $( '
' ).html( attr_val ).text(); - // Attach. - new_attr_select.find( 'option[value="' + form.addSlashes( attr_val ) + '"]' ).addClass( 'attached ' + variation_active ); + // Attach to matching options by value. This is done to compare + // TEXT values rather than any HTML entities. + new_attr_select.find( 'option' ).each( function( index, el ) { + var option_value = $( this ).val(); + + if ( attr_val === option_value ) { + $( this ).addClass( 'attached ' + variation_active ); + return false; // break. + } + }); } else { // Attach all apart from placeholder. new_attr_select.find( 'option:gt(0)' ).addClass( 'attached ' + variation_active ); @@ -371,8 +379,19 @@ attached_options_count = new_attr_select.find( 'option.attached' ).length; // Check if current selection is in attached options. - if ( selected_attr_val && ( attached_options_count === 0 || new_attr_select.find( 'option.attached.enabled[value="' + form.addSlashes( selected_attr_val ) + '"]' ).length === 0 ) ) { + if ( selected_attr_val ) { selected_attr_val_valid = false; + + if ( 0 !== attached_options_count ) { + new_attr_select.find( 'option.attached.enabled' ).each( function( index, el ) { + var option_value = $( this ).val(); + + if ( selected_attr_val === option_value ) { + selected_attr_val_valid = true; + return false; // break. + } + }); + } } // Detach the placeholder if: diff --git a/includes/admin/meta-boxes/class-wc-meta-box-product-data.php b/includes/admin/meta-boxes/class-wc-meta-box-product-data.php index 1219d40fcd6..f463f6af277 100644 --- a/includes/admin/meta-boxes/class-wc-meta-box-product-data.php +++ b/includes/admin/meta-boxes/class-wc-meta-box-product-data.php @@ -228,7 +228,7 @@ class WC_Meta_Box_Product_Data { $attributes = array(); if ( ! $data ) { - $data = $_POST; + $data = stripslashes_deep( $_POST ); } if ( isset( $data['attribute_names'], $data['attribute_values'] ) ) { diff --git a/includes/class-wc-ajax.php b/includes/class-wc-ajax.php index 10f2d397901..07036735d26 100644 --- a/includes/class-wc-ajax.php +++ b/includes/class-wc-ajax.php @@ -618,7 +618,7 @@ class WC_AJAX { $response = array(); try { - parse_str( $_POST['data'], $data ); + parse_str( wp_unslash( $_POST['data'] ), $data ); $attributes = WC_Meta_Box_Product_Data::prepare_attributes( $data ); $product_id = absint( $_POST['post_id'] ); diff --git a/includes/data-stores/class-wc-product-data-store-cpt.php b/includes/data-stores/class-wc-product-data-store-cpt.php index c3b0b6c6b59..25a3c2ce211 100644 --- a/includes/data-stores/class-wc-product-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-data-store-cpt.php @@ -764,7 +764,8 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da ); } } - update_post_meta( $product->get_id(), '_product_attributes', $meta_values ); + // Note, we use wp_slash to add extra level of escaping. See https://codex.wordpress.org/Function_Reference/update_post_meta#Workaround. + update_post_meta( $product->get_id(), '_product_attributes', wp_slash( $meta_values ) ); } } diff --git a/includes/data-stores/class-wc-product-variation-data-store-cpt.php b/includes/data-stores/class-wc-product-variation-data-store-cpt.php index 80aff7b5020..fc1e3c08085 100644 --- a/includes/data-stores/class-wc-product-variation-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-variation-data-store-cpt.php @@ -428,7 +428,7 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl $attributes = $product->get_attributes(); $updated_attribute_keys = array(); foreach ( $attributes as $key => $value ) { - update_post_meta( $product->get_id(), 'attribute_' . $key, $value ); + update_post_meta( $product->get_id(), 'attribute_' . $key, wp_slash( $value ) ); $updated_attribute_keys[] = 'attribute_' . $key; } diff --git a/includes/wc-attribute-functions.php b/includes/wc-attribute-functions.php index 6a02dc278aa..d913d0da1c3 100644 --- a/includes/wc-attribute-functions.php +++ b/includes/wc-attribute-functions.php @@ -94,10 +94,10 @@ function wc_attribute_taxonomy_name_by_id( $attribute_id ) { $attribute_name = $wpdb->get_var( $wpdb->prepare( " - SELECT attribute_name - FROM {$wpdb->prefix}woocommerce_attribute_taxonomies - WHERE attribute_id = %d - ", + SELECT attribute_name + FROM {$wpdb->prefix}woocommerce_attribute_taxonomies + WHERE attribute_id = %d + ", $attribute_id ) ); @@ -384,10 +384,10 @@ function wc_get_attribute( $id ) { $data = $wpdb->get_row( $wpdb->prepare( " - SELECT * - FROM {$wpdb->prefix}woocommerce_attribute_taxonomies - WHERE attribute_id = %d - ", + SELECT * + FROM {$wpdb->prefix}woocommerce_attribute_taxonomies + WHERE attribute_id = %d + ", $id ) ); @@ -558,7 +558,7 @@ function wc_create_attribute( $args ) { $unserialized_data[ $new_taxonomy_name ] = $unserialized_data[ $old_taxonomy_name ]; unset( $unserialized_data[ $old_taxonomy_name ] ); $unserialized_data[ $new_taxonomy_name ]['name'] = $new_taxonomy_name; - update_post_meta( $product_id, '_product_attributes', $unserialized_data ); + update_post_meta( $product_id, '_product_attributes', wp_slash( $unserialized_data ) ); } // Update variations which use this taxonomy. @@ -625,10 +625,10 @@ function wc_delete_attribute( $id ) { $name = $wpdb->get_var( $wpdb->prepare( " - SELECT attribute_name - FROM {$wpdb->prefix}woocommerce_attribute_taxonomies - WHERE attribute_id = %d - ", + SELECT attribute_name + FROM {$wpdb->prefix}woocommerce_attribute_taxonomies + WHERE attribute_id = %d + ", $id ) );