-
-
Notifications
You must be signed in to change notification settings - Fork 522
Description
Bug Description
The ContextHelper::is_in_function_call() method has a bug when handling namespaced function calls that share their name with a global function in the $valid_functions list.
When called with $global_function = true and $allow_nested = false (the default parameters), if the immediate wrapping function is namespaced, but its name matches a valid function, is_in_function_call() incorrectly continues searching outer parentheses instead of returning false.
This causes false negatives in the ValidatedSanitizedInput sniff, which calls is_in_function_call() via is_sanitized() with those default parameters.
Minimal Code Snippet
The issue happens when running this command:
phpcs --standard=WordPress --sniffs=WordPress.Security.ValidatedSanitizedInput -s test.php... over a file containing this code:
if ( isset( $_POST['data'] ) ) {
$text = sanitize_text_field( MyNamespace\wp_unslash( $_POST['data'] ) );
}Expected: 2 errors - MissingUnslash and InputNotSanitized
Actual: 1 error - only MissingUnslash
Environment
| Question | Answer |
|---|---|
| PHP version | 8.4 |
| PHP_CodeSniffer version | 3.13.5 |
| WordPressCS version | develop |
| PHPCSUtils version | 1.2.1 |
| PHPCSExtra version | 1.5.0 |
| WordPressCS install type | git clone |
| IDE (if relevant) | N/A |
Additional Context
The problem happens when ContextHelper::is_in_function_call() iterates through nested parentheses. It handles two scenarios differently:
- Function NOT in
$valid_functions: The method correctly checks$allow_nestedand returnsfalseif$allow_nested = false. - Function IN
$valid_functionsbut namespaced (not global): The method unconditionally continues to check outer parentheses, ignoring the$allow_nestedparameter.
In the second scenario, when $allow_nested = false, the method should return false instead of continuing. The namespaced function MyNamespace\wp_unslash() is a different function from the global wp_unslash(), so it should be treated the same as any other unrecognized function.
WordPress-Coding-Standards/WordPress/Helpers/ContextHelper.php
Lines 236 to 243 in 013dc81
| if ( isset( $valid_functions[ strtolower( $tokens[ $prev_non_empty ]['content'] ) ] ) === false ) { | |
| if ( false === $allow_nested ) { | |
| // Function call encountered, but not to one of the allowed functions. | |
| return false; | |
| } | |
| continue; | |
| } |
This bug only happens when using PHPCS 3.x. It does not happen in PHPCS 4.x as namespaced tokens are tokenized differently. Since this was not reported before, I'm inclined to think it is not necessary to fix this bug, and this issue can be closed once support for PHPCS 3.x is dropped. The namespaced names tests that I prepared for ValidatedSanitizedInput include tests that document this problem.
Tested Against develop Branch?
- I have verified the issue still exists in the
developbranch of WordPressCS.