Commit 125544ae2f9 for woocommerce

commit 125544ae2f946ec57417f4ceed972f7f660910cd
Author: Darren Ethier <darren@roughsmootheng.in>
Date:   Wed Sep 2 13:31:19 2026 -0400

    Scope widget output suppressions to current PHPCS sniffs (#68267)

diff --git a/plugins/woocommerce/changelog/fix-woo6-124-widget-html-rendering-suppressions b/plugins/woocommerce/changelog/fix-woo6-124-widget-html-rendering-suppressions
new file mode 100644
index 00000000000..a8a072b6e34
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-woo6-124-widget-html-rendering-suppressions
@@ -0,0 +1,4 @@
+Significance: patch
+Type: dev
+
+Replace legacy WPCS suppression comments in the widget rendering paths with exact PHPCS annotations, and run the remaining widget form setting labels through wp_kses_post().
diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-widget.php b/plugins/woocommerce/includes/abstracts/abstract-wc-widget.php
index 4aab2cef4c8..9e7f653125b 100644
--- a/plugins/woocommerce/includes/abstracts/abstract-wc-widget.php
+++ b/plugins/woocommerce/includes/abstracts/abstract-wc-widget.php
@@ -93,7 +93,7 @@ abstract class WC_Widget extends WP_Widget {
 		}

 		if ( isset( $cache[ $this->get_widget_id_for_cache( $args['widget_id'] ) ] ) ) {
-			echo $cache[ $this->get_widget_id_for_cache( $args['widget_id'] ) ]; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
+			echo $cache[ $this->get_widget_id_for_cache( $args['widget_id'] ) ]; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Widget markup that was already escaped when it was rendered into the cache.
 			return true;
 		}

@@ -160,12 +160,12 @@ abstract class WC_Widget extends WP_Widget {
 	 * @param array $instance Instance.
 	 */
 	public function widget_start( $args, $instance ) {
-		echo $args['before_widget']; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
+		echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Sidebar wrapper markup supplied by the theme via register_sidebar().

 		$title = apply_filters( 'widget_title', $this->get_instance_title( $instance ), $instance, $this->id_base );

 		if ( $title ) {
-			echo $args['before_title'] . $title . $args['after_title']; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
+			echo $args['before_title'] . $title . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Theme-supplied title wrappers around the widget_title filtered value.
 		}
 	}

@@ -175,7 +175,7 @@ abstract class WC_Widget extends WP_Widget {
 	 * @param  array $args Arguments.
 	 */
 	public function widget_end( $args ) {
-		echo $args['after_widget']; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
+		echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Sidebar wrapper markup supplied by the theme via register_sidebar().
 	}

 	/**
@@ -267,7 +267,7 @@ abstract class WC_Widget extends WP_Widget {
 				case 'number':
 					?>
 					<p>
-						<label for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo $setting['label']; /* phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped */ ?></label>
+						<label for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo wp_kses_post( $setting['label'] ); ?></label>
 						<input class="widefat <?php echo esc_attr( $class ); ?>" id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>" type="number" step="<?php echo esc_attr( $setting['step'] ); ?>" min="<?php echo esc_attr( $setting['min'] ); ?>" max="<?php echo esc_attr( $setting['max'] ); ?>" value="<?php echo esc_attr( $value ); ?>" />
 					</p>
 					<?php
@@ -276,7 +276,7 @@ abstract class WC_Widget extends WP_Widget {
 				case 'select':
 					?>
 					<p>
-						<label for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo $setting['label']; /* phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped */ ?></label>
+						<label for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo wp_kses_post( $setting['label'] ); ?></label>
 						<select class="widefat <?php echo esc_attr( $class ); ?>" id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>">
 							<?php foreach ( $setting['options'] as $option_key => $option_value ) : ?>
 								<option value="<?php echo esc_attr( $option_key ); ?>" <?php selected( $option_key, $value ); ?>><?php echo esc_html( $option_value ); ?></option>
@@ -289,7 +289,7 @@ abstract class WC_Widget extends WP_Widget {
 				case 'textarea':
 					?>
 					<p>
-						<label for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo $setting['label']; /* phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped */ ?></label>
+						<label for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo wp_kses_post( $setting['label'] ); ?></label>
 						<textarea class="widefat <?php echo esc_attr( $class ); ?>" id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>" cols="20" rows="3"><?php echo esc_textarea( $value ); ?></textarea>
 						<?php if ( isset( $setting['desc'] ) ) : ?>
 							<small><?php echo esc_html( $setting['desc'] ); ?></small>
@@ -302,7 +302,7 @@ abstract class WC_Widget extends WP_Widget {
 					?>
 					<p>
 						<input class="checkbox <?php echo esc_attr( $class ); ?>" id="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $key ) ); ?>" type="checkbox" value="1" <?php checked( $value, 1 ); ?> />
-						<label for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo $setting['label']; /* phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped */ ?></label>
+						<label for="<?php echo esc_attr( $this->get_field_id( $key ) ); ?>"><?php echo wp_kses_post( $setting['label'] ); ?></label>
 					</p>
 					<?php
 					break;
diff --git a/plugins/woocommerce/includes/widgets/class-wc-widget-layered-nav-filters.php b/plugins/woocommerce/includes/widgets/class-wc-widget-layered-nav-filters.php
index 960161b7dbd..efc8ec95512 100644
--- a/plugins/woocommerce/includes/widgets/class-wc-widget-layered-nav-filters.php
+++ b/plugins/woocommerce/includes/widgets/class-wc-widget-layered-nav-filters.php
@@ -105,13 +105,13 @@ class WC_Widget_Layered_Nav_Filters extends WC_Widget {
 			if ( $min_price ) {
 				$link = remove_query_arg( 'min_price', $base_link );
 				/* translators: %s: minimum price */
-				echo '<li class="chosen"><a rel="nofollow" aria-label="' . esc_attr__( 'Remove filter', 'woocommerce' ) . '" href="' . esc_url( $link ) . '">' . sprintf( __( 'Min %s', 'woocommerce' ), wc_price( $min_price ) ) . '</a></li>'; // WPCS: XSS ok.
+				echo '<li class="chosen"><a rel="nofollow" aria-label="' . esc_attr__( 'Remove filter', 'woocommerce' ) . '" href="' . esc_url( $link ) . '">' . sprintf( esc_html__( 'Min %s', 'woocommerce' ), wc_price( $min_price ) ) . '</a></li>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- wc_price() returns formatted price markup.
 			}

 			if ( $max_price ) {
 				$link = remove_query_arg( 'max_price', $base_link );
 				/* translators: %s: maximum price */
-				echo '<li class="chosen"><a rel="nofollow" aria-label="' . esc_attr__( 'Remove filter', 'woocommerce' ) . '" href="' . esc_url( $link ) . '">' . sprintf( __( 'Max %s', 'woocommerce' ), wc_price( $max_price ) ) . '</a></li>'; // WPCS: XSS ok.
+				echo '<li class="chosen"><a rel="nofollow" aria-label="' . esc_attr__( 'Remove filter', 'woocommerce' ) . '" href="' . esc_url( $link ) . '">' . sprintf( esc_html__( 'Max %s', 'woocommerce' ), wc_price( $max_price ) ) . '</a></li>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- wc_price() returns formatted price markup.
 			}

 			if ( ! empty( $rating_filter ) ) {
diff --git a/plugins/woocommerce/includes/widgets/class-wc-widget-products.php b/plugins/woocommerce/includes/widgets/class-wc-widget-products.php
index f7bd9432609..50f1d6b3bf3 100644
--- a/plugins/woocommerce/includes/widgets/class-wc-widget-products.php
+++ b/plugins/woocommerce/includes/widgets/class-wc-widget-products.php
@@ -217,6 +217,6 @@ class WC_Widget_Products extends WC_Widget {

 		wp_reset_postdata();

-		echo $this->cache_widget( $args, ob_get_clean() ); // WPCS: XSS ok.
+		echo $this->cache_widget( $args, ob_get_clean() ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Buffered widget markup; each dynamic value is escaped or annotated where it is rendered.
 	}
 }
diff --git a/plugins/woocommerce/includes/widgets/class-wc-widget-rating-filter.php b/plugins/woocommerce/includes/widgets/class-wc-widget-rating-filter.php
index bbc2b1644b5..962ff198a4b 100644
--- a/plugins/woocommerce/includes/widgets/class-wc-widget-rating-filter.php
+++ b/plugins/woocommerce/includes/widgets/class-wc-widget-rating-filter.php
@@ -131,7 +131,7 @@ class WC_Widget_Rating_Filter extends WC_Widget {
 				)
 			);

-			printf( '<li class="%s"><a href="%s"><span class="star-rating">%s</span> %s</a></li>', esc_attr( $class ), esc_url( $link ), $rating_html, $count_html ); // WPCS: XSS ok.
+			printf( '<li class="%s"><a href="%s"><span class="star-rating">%s</span> %s</a></li>', esc_attr( $class ), esc_url( $link ), $rating_html, $count_html ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Star rating markup from wc_get_star_rating_html() and a count already run through wp_kses().
 		}

 		echo '</ul>';
@@ -141,7 +141,7 @@ class WC_Widget_Rating_Filter extends WC_Widget {
 		if ( ! $found ) {
 			ob_end_clean();
 		} else {
-			echo ob_get_clean(); // WPCS: XSS ok.
+			echo ob_get_clean(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Buffered widget markup; each dynamic value is escaped or annotated where it is rendered.
 		}
 	}
 }
diff --git a/plugins/woocommerce/includes/widgets/class-wc-widget-recent-reviews.php b/plugins/woocommerce/includes/widgets/class-wc-widget-recent-reviews.php
index 20b30b974fb..b5243e2ce29 100644
--- a/plugins/woocommerce/includes/widgets/class-wc-widget-recent-reviews.php
+++ b/plugins/woocommerce/includes/widgets/class-wc-widget-recent-reviews.php
@@ -91,7 +91,7 @@ class WC_Widget_Recent_Reviews extends WC_Widget {

 		$content = ob_get_clean();

-		echo $content; // WPCS: XSS ok.
+		echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Buffered widget markup; each dynamic value is escaped or annotated where it is rendered.

 		$this->cache_widget( $args, $content );
 	}
diff --git a/plugins/woocommerce/includes/widgets/class-wc-widget-recently-viewed.php b/plugins/woocommerce/includes/widgets/class-wc-widget-recently-viewed.php
index 466e851a5ab..f58514aed32 100644
--- a/plugins/woocommerce/includes/widgets/class-wc-widget-recently-viewed.php
+++ b/plugins/woocommerce/includes/widgets/class-wc-widget-recently-viewed.php
@@ -107,6 +107,6 @@ class WC_Widget_Recently_Viewed extends WC_Widget {

 		$content = ob_get_clean();

-		echo $content; // WPCS: XSS ok.
+		echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Buffered widget markup; each dynamic value is escaped or annotated where it is rendered.
 	}
 }
diff --git a/plugins/woocommerce/includes/widgets/class-wc-widget-top-rated-products.php b/plugins/woocommerce/includes/widgets/class-wc-widget-top-rated-products.php
index e6d95bf17db..cc7663f8fb9 100644
--- a/plugins/woocommerce/includes/widgets/class-wc-widget-top-rated-products.php
+++ b/plugins/woocommerce/includes/widgets/class-wc-widget-top-rated-products.php
@@ -100,7 +100,7 @@ class WC_Widget_Top_Rated_Products extends WC_Widget {

 		$content = ob_get_clean();

-		echo $content; // WPCS: XSS ok.
+		echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Buffered widget markup; each dynamic value is escaped or annotated where it is rendered.

 		$this->cache_widget( $args, $content );
 	}