Commit 64a42954fe9 for woocommerce

commit 64a42954fe92cf92573de791551528e6f7851593
Author: Chris Lilitsas <1105590+xristos3490@users.noreply.github.com>
Date:   Fri Oct 23 17:10:38 2026 +0300

    Escape the order status tooltip as an attribute in the orders list (#70061)

    fix: escape order status tooltip as an attribute in the orders list

    The tooltip went through wp_kses_post() into data-tip. On WordPress 7.2
    kses decodes &quot; in text, so a quote in a status label closed the
    attribute. Use esc_attr() instead.

diff --git a/plugins/woocommerce/changelog/fix-order-status-tooltip-escaping b/plugins/woocommerce/changelog/fix-order-status-tooltip-escaping
new file mode 100644
index 00000000000..70103d09608
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-order-status-tooltip-escaping
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Escape the order status tooltip in the orders list as an attribute, so quotes in a status label no longer break its markup on WordPress 7.2.
diff --git a/plugins/woocommerce/src/Internal/Admin/Orders/ListTable.php b/plugins/woocommerce/src/Internal/Admin/Orders/ListTable.php
index 65716f679a2..aa41aef1435 100644
--- a/plugins/woocommerce/src/Internal/Admin/Orders/ListTable.php
+++ b/plugins/woocommerce/src/Internal/Admin/Orders/ListTable.php
@@ -1238,7 +1238,7 @@ class ListTable extends WP_List_Table {
 		}

 		if ( $tooltip ) {
-			printf( '<mark class="order-status %s tips" data-tip="%s"><span>%s</span></mark>', esc_attr( sanitize_html_class( 'status-' . $order->get_status() ) ), wp_kses_post( $tooltip ), esc_html( $status_name ) );
+			printf( '<mark class="order-status %s tips" data-tip="%s"><span>%s</span></mark>', esc_attr( sanitize_html_class( 'status-' . $order->get_status() ) ), esc_attr( $tooltip ), esc_html( $status_name ) );
 		} else {
 			printf( '<mark class="order-status %s"><span>%s</span></mark>', esc_attr( sanitize_html_class( 'status-' . $order->get_status() ) ), esc_html( $status_name ) );
 		}
diff --git a/plugins/woocommerce/tests/php/src/Internal/Admin/Orders/ListTableTest.php b/plugins/woocommerce/tests/php/src/Internal/Admin/Orders/ListTableTest.php
index e962a51cfb6..5e869b945cf 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Admin/Orders/ListTableTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Admin/Orders/ListTableTest.php
@@ -493,6 +493,30 @@ class ListTableTest extends \WC_Unit_Test_Case {
 		$this->assertCount( 2, $items, 'An invalid date filter should be ignored and all orders shown' );
 	}

+	/**
+	 * @testdox Quotes in an order status label cannot break out of the status column tooltip attribute.
+	 */
+	public function test_render_order_status_column_escapes_tooltip_attribute(): void {
+		$order = \WC_Helper_Order::create_order();
+		$order->set_status( OrderStatus::PROCESSING );
+		$order->save();
+
+		$filter = function ( $labels ) {
+			$labels[ OrderStatus::PROCESSING ] = 'Paid" onmouseover="alert(1)';
+			return $labels;
+		};
+		add_filter( 'woocommerce_get_order_status_labels', $filter );
+
+		ob_start();
+		$this->sut->render_order_status_column( $order );
+		$output = ob_get_clean();
+
+		remove_filter( 'woocommerce_get_order_status_labels', $filter );
+
+		$this->assertStringContainsString( 'data-tip="Paid&quot; onmouseover=&quot;alert(1)"', $output );
+		$this->assertStringNotContainsString( 'onmouseover="', $output );
+	}
+
 	/**
 	 * @testdox Ordering by date also orders by ID, so orders created at the same time keep a stable order.
 	 * @testWith [{}]