From 82673fe0d8d08b9fab6270ab82ec58877ced4b8f Mon Sep 17 00:00:00 2001 From: Carlos Bravo <37012961+cbravobernal@users.noreply.github.com> Date: Fri, 12 Jun 2026 14:20:51 +0200 Subject: [PATCH] Add backslash coverage to wp_options LIKE escaping tests The escaping tests asserted % and _ are escaped, and the comments note esc_like() also covers the \ escape character, but no case exercised it. Add a backslash-prefix case to both the option-meta and parity tests; each was confirmed to fail against the previous str_replace('_','\_') escaping (which left \ active) and pass with esc_like(). Co-Authored-By: Claude Fable 5 --- .../test-acf-option-meta-like-escaping.php | 26 +++++++++++++++++++ .../includes/test-like-escaping-parity.php | 25 ++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/tests/php/includes/functions/test-acf-option-meta-like-escaping.php b/tests/php/includes/functions/test-acf-option-meta-like-escaping.php index d3d15070..c52edf09 100644 --- a/tests/php/includes/functions/test-acf-option-meta-like-escaping.php +++ b/tests/php/includes/functions/test-acf-option-meta-like-escaping.php @@ -118,6 +118,32 @@ public function test_underscore_prefix_is_escaped() { ); } + /** + * A prefix containing a backslash must be escaped. + */ + public function test_backslash_prefix_is_escaped() { + global $wpdb; + + // The prefix is the three characters a \ b. + acf_get_option_meta( 'a\\b' ); + + $good = $this->expected_like_fragment( 'a\\b_' ); + $this->assertStringContainsString( + $good, + $this->captured_sql, + 'A backslash in the prefix should be escaped via esc_like().' + ); + + // The previous str_replace() approach escaped only `_`, leaving the + // backslash unescaped. That exact fragment must not appear. + $bad = $wpdb->prepare( '%s', str_replace( '_', '\_', 'a\\b_%' ) ); + $this->assertStringNotContainsString( + $bad, + $this->captured_sql, + 'The pattern with an unescaped backslash must not be generated.' + ); + } + /** * A benign prefix still produces the expected (unchanged) pattern. */ diff --git a/tests/php/includes/test-like-escaping-parity.php b/tests/php/includes/test-like-escaping-parity.php index dd33217f..cc4eb9e7 100644 --- a/tests/php/includes/test-like-escaping-parity.php +++ b/tests/php/includes/test-like-escaping-parity.php @@ -102,6 +102,31 @@ public function test_upgrade_550_taxonomy_escapes_like() { ); } + /** + * Ensures acf_upgrade_550_taxonomy() also escapes a backslash. + */ + public function test_upgrade_550_taxonomy_escapes_backslash() { + global $wpdb; + + // The taxonomy is the three characters a \ b. + acf_upgrade_550_taxonomy( 'a\\b' ); + + $query = $this->last_query(); + $this->assertNotEmpty( $query, 'The upgrade SELECT should have been captured.' ); + $this->assertStringContainsString( + $this->expected_fragment( 'a\\b_' ), + $query, + 'A backslash should be escaped via esc_like().' + ); + + $bad = $wpdb->prepare( '%s', str_replace( '_', '\_', 'a\\b_%' ) ); + $this->assertStringNotContainsString( + $bad, + $query, + 'The pattern with an unescaped backslash must not be generated.' + ); + } + /** * Ensures acf_form_taxonomy::delete_term() escapes the taxonomy and term * in its legacy (no-termmeta) DELETE.