Skip to content

Commit 799b3e7

Browse files
committed
DB/PreparedSQL: add tests for namespaced names
1 parent c0db6ba commit 799b3e7

2 files changed

Lines changed: 83 additions & 2 deletions

File tree

WordPress/Tests/DB/PreparedSQLUnitTest.1.inc

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ $wpdb->query( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . esc_sql( $f
3333
$wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . ABSINT( $foo ) . ";" ); // Ok.
3434

3535
// Test multi-line strings.
36-
$all_post_meta = $wpdb->get_results( $wpdb->prepare( sprintf(
36+
$all_post_meta = $wpdb->get_results( $wpdb->prepare( \SPRINTF(
3737
'SELECT `post_id`, `meta_value`
3838
FROM `%s`
3939
WHERE `meta_key` = "sort_order"
@@ -45,7 +45,7 @@ $all_post_meta = $wpdb->get_results( $wpdb->prepare( sprintf(
4545
$wpdb->query( "
4646
SELECT *
4747
FROM $wpdb->posts
48-
WHERE post_title LIKE '" . esc_sql( $foo ) . "';"
48+
WHERE post_title LIKE '" . \esc_SQL( $foo ) . "';"
4949
); // Ok.
5050

5151
$wpdb->query( $wpdb->prepare( "
@@ -142,3 +142,61 @@ echo $wpdb::CONSTANT_NAME;
142142

143143
// Not an identifiable method call.
144144
$wpdb->{$methodName}('query');
145+
146+
/*
147+
* Safeguard correct handling of all types of namespaced calls to the WPDB::prepare() method.
148+
*
149+
* Note that calling wpdb::prepare() statically will result in an error. Still, the tests are included here since the
150+
* sniff handles those calls.
151+
*
152+
* Except for the fully qualified global call, the calls below are currently false positives. The sniff
153+
* incorrectly identifies calls to a non-global class named `wpdb` preceded by a namespace separator as calls to the
154+
* global `$wpdb` object. Related to: https://github.com/WordPress/WordPress-Coding-Standards/issues/2710.
155+
*/
156+
\WPDB::prepare( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . foo() . "';" );
157+
MyNamespace\WPDB::prepare( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . foo() . "';" );
158+
\MyNamespace\wpdb::prepare( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . foo() . "';" );
159+
namespace\wpdb::prepare( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . foo() . "';" ); // False positive (see comment above). This should be flagged in the future once the sniff is able to resolve relative namespaces.
160+
namespace\Sub\wpdb::prepare( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . foo() . "';" );
161+
162+
/*
163+
* Safeguard correct handling of all types of namespaced calls to PreparedSQLSniff::$SQLEscapingFunctions.
164+
*
165+
* Note: The sniff currently has a limitation in how it identifies and counts errors for namespaced function calls that
166+
* match function names in $SQLEscapingFunctions, $SQLAutoEscapedFunctions, or
167+
* FormattingFunctionsHelper::$formattingFunctions. When it encounters such a call, it treats the function name as if it
168+
* were a global function call and skips checking the contents. For example, `MyNamespace\absint( $foo )` should trigger
169+
* two errors (one for MyNamespace\absint, one for $foo), but currently only triggers one error for "MyNamespace"
170+
* because the sniff incorrectly treats "absint" as a valid global escaping function and skips its contents.
171+
* Additionally, multi-level namespace calls like `namespace\Sub\count( $foo )` generate multiple errors (one for
172+
* "namespace", one for "Sub") instead of recognizing it as a single namespaced function call. This will be easier to
173+
* fix once only PHPCS 4 is supported. Reported in https://github.com/WordPress/WordPress-Coding-Standards/issues/2648.
174+
*/
175+
$wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . \absint( $foo ) );
176+
$wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . MyNamespace\esc_sql( $foo ) );
177+
$wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . \MyNamespace\intval( $foo ) );
178+
$wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . namespace\floatval( $foo ) ); // This should NOT be flagged in the future once the sniff is able to resolve relative namespaces.
179+
$wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . namespace\Sub\like_escape( $foo ) );
180+
181+
/*
182+
* Safeguard correct handling of all types of namespaced calls to PreparedSQLSniff::$SQLAutoEscapedFunctions.
183+
*
184+
* Note: See the comment above the $SQLEscapingFunctions tests for details about the sniff's current limitations.
185+
*/
186+
$wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . \count( $foo ) );
187+
$wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . \Count( $foo ) );
188+
$wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . MyNamespace\count( $foo ) );
189+
$wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . \MyNamespace\count( $foo ) );
190+
$wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . namespace\count( $foo ) ); // This should NOT be flagged in the future once the sniff is able to resolve relative namespaces.
191+
$wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . namespace\Sub\count( $foo ) );
192+
193+
/*
194+
* Safeguard correct handling of all types of namespaced calls to FormattingFunctionsHelper::$formattingFunctions.
195+
*
196+
* Note: See the comment above the $SQLEscapingFunctions tests for details about the sniff's current limitations.
197+
*/
198+
$wpdb->get_results( \sprintf( "SELECT * FROM $wpdb->posts WHERE ID = %s", intval( $id ) ) );
199+
$wpdb->get_results( MyNamespace\wp_sprintf( "SELECT * FROM $wpdb->posts WHERE ID = %s", intval( $id ) ) );
200+
$wpdb->get_results( \MyNamespace\sprintf( "SELECT * FROM $wpdb->posts WHERE ID = %s", intval( $id ) ) );
201+
$wpdb->get_results( namespace\wp_sprintf( "SELECT * FROM $wpdb->posts WHERE ID = %s", intval( $id ) ) ); // This should NOT be flagged in the future once the sniff is able to resolve relative namespaces.
202+
$wpdb->get_results( namespace\Sub\sprintf( "SELECT * FROM $wpdb->posts WHERE ID = %s", intval( $id ) ) );

WordPress/Tests/DB/PreparedSQLUnitTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,29 @@ public function getErrorList( $testFile = '' ) {
6666
124 => 1,
6767
128 => 1,
6868
132 => 2,
69+
156 => 1,
70+
71+
/**
72+
* False positives. See https://github.com/WordPress/WordPress-Coding-Standards/issues/2710 and
73+
* comment in the test case file.
74+
*/
75+
157 => 1,
76+
158 => 1,
77+
159 => 1,
78+
160 => 1,
79+
80+
176 => 1,
81+
177 => 1,
82+
178 => 1,
83+
179 => 2,
84+
188 => 1,
85+
189 => 1,
86+
190 => 1,
87+
191 => 2,
88+
199 => 1,
89+
200 => 1,
90+
201 => 1,
91+
202 => 2,
6992
);
7093

7194
case 'PreparedSQLUnitTest.2.inc':

0 commit comments

Comments
 (0)