From f51cb5d6acba9cdab5f572f0f8de11265bceb2fc Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 21 Aug 2025 16:47:14 -0300 Subject: [PATCH 1/3] WP/AlternativeFunctions: add tests for namespaced names --- WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc | 11 ++++++++++- WordPress/Tests/WP/AlternativeFunctionsUnitTest.php | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc index a88e5638a9..6296d75e22 100644 --- a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc +++ b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc @@ -32,7 +32,7 @@ file_get_contents( $local_file, true ); // OK. file_get_contents( $url, false ); // Warning. file_get_contents(); // OK - no params, so nothing to do. file_get_contents( 'http://remoteurl.com/file/?w=1' ); // Warning. -file_get_contents( 'https://wordpress.org' ); // Warning. +\file_GET_contents( 'https://wordpress.org' ); // Warning. file_get_contents(ABSPATH . 'wp-admin/css/some-file.css'); // OK. file_get_contents(MYABSPATH . 'plugin-file.json'); // Warning. file_get_contents( MUPLUGINDIR . 'some-file.xml' ); // OK. @@ -147,3 +147,12 @@ file_get_contents( // Not using plugin_dir_path() for reasons. $url ); // Warning. + +/* + * Safeguard correct handling of all types of namespaced function calls + */ +\curl_init(); +MyNamespace\parse_url( 'http://example.com/' ); +\MyNamespace\json_encode( $data ); +namespace\unlink(); // The sniff should start flagging this once it can resolve relative namespaces. +namespace\Sub\strip_tags( $string ); diff --git a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php index b0f1bf96aa..e660886adb 100644 --- a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php +++ b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php @@ -89,6 +89,7 @@ public function getWarningList() { 131 => 1, 142 => 1, 146 => 1, + 154 => 1, ); } } From 15c8cb7928d4a7dc7caaf33cc47c1798891f1ea0 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Tue, 16 Sep 2025 15:38:49 -0300 Subject: [PATCH 2/3] WP/AlternativeFunctions: improve regex to distinguish global WP constants/functions from non-WP class-based ones This commit changes two regexes used to identify global WP constants and functions to prevent the sniff from incorrectly identifying class constants/methods with the same names as WordPress globals as being WordPress globals. This is done by adding a negative lookbehind to ensure the searched strings are not preceded by an object operator, null-safe object operator, or scope resolution operator. Fixes part of 2603 --- WordPress/Sniffs/WP/AlternativeFunctionsSniff.php | 4 ++-- WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc | 11 +++++++++++ WordPress/Tests/WP/AlternativeFunctionsUnitTest.php | 6 ++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/WordPress/Sniffs/WP/AlternativeFunctionsSniff.php b/WordPress/Sniffs/WP/AlternativeFunctionsSniff.php index 40fb0c61c2..b773036576 100644 --- a/WordPress/Sniffs/WP/AlternativeFunctionsSniff.php +++ b/WordPress/Sniffs/WP/AlternativeFunctionsSniff.php @@ -283,7 +283,7 @@ public function process_matched_token( $stackPtr, $group_name, $matched_content } $contains_wp_path_constant = preg_match( - '`\b(?:ABSPATH|WP_(?:CONTENT|PLUGIN)_DIR|WPMU_PLUGIN_DIR|TEMPLATEPATH|STYLESHEETPATH|(?:MU)?PLUGINDIR)\b`', + '`(?|::)\b(?:ABSPATH|WP_(?:CONTENT|PLUGIN)_DIR|WPMU_PLUGIN_DIR|TEMPLATEPATH|STYLESHEETPATH|(?:MU)?PLUGINDIR)\b`', $filename_param['clean'] ); if ( 1 === $contains_wp_path_constant ) { @@ -292,7 +292,7 @@ public function process_matched_token( $stackPtr, $group_name, $matched_content } $contains_wp_path_function_call = preg_match( - '`(?:get_home_path|plugin_dir_path|get_(?:stylesheet|template)_directory|wp_upload_dir)\s*\(`i', + '`(?|::)(?:get_home_path|plugin_dir_path|get_(?:stylesheet|template)_directory|wp_upload_dir)\s*\(`i', $filename_param['clean'] ); if ( 1 === $contains_wp_path_function_call ) { diff --git a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc index 6296d75e22..067178fb7a 100644 --- a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc +++ b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc @@ -156,3 +156,14 @@ MyNamespace\parse_url( 'http://example.com/' ); \MyNamespace\json_encode( $data ); namespace\unlink(); // The sniff should start flagging this once it can resolve relative namespaces. namespace\Sub\strip_tags( $string ); + +/* + * Safeguard that the sniff does not incorrectly ignore class methods/constants with the same + * name as WordPress global functions/constants when used in file_get_contents(). + */ +file_get_contents( MyClass::wp_upload_dir() . 'subdir/file.inc' ); +file_get_contents( $this->GET_HOME_PATH() . 'subdir/file.inc' ); +file_get_contents( $this?->plugin_dir_path() . 'subdir/file.inc' ); +file_get_contents( MyClass::ABSPATH . 'subdir/file.inc' ); +file_get_contents( $this->WPMU_PLUGIN_DIR . 'subdir/file.inc' ); +file_get_contents( $this?->TEMPLATEPATH . 'subdir/file.inc' ); diff --git a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php index e660886adb..7aa4dccbb9 100644 --- a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php +++ b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php @@ -90,6 +90,12 @@ public function getWarningList() { 142 => 1, 146 => 1, 154 => 1, + 164 => 1, + 165 => 1, + 166 => 1, + 167 => 1, + 168 => 1, + 169 => 1, ); } } From e95a98f54046bd0aa9e98fc66ff3ab023e0fd381 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Mon, 24 Nov 2025 12:32:47 -0300 Subject: [PATCH 3/3] WP/AlternativeFunctions: fix handling of FQN references to global stream constants This commit fixes the handling of fully qualified name (FQN) references to the global PHP stream constants `\STDIN`, `\STDOUT`, and `\STDERR` by normalizing the passed parameter before checking it against the allowed list. Tests have been added to cover all namespace forms of references to the global PHP stream constants. --- WordPress/Sniffs/WP/AlternativeFunctionsSniff.php | 4 +++- WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc | 13 +++++++++++++ WordPress/Tests/WP/AlternativeFunctionsUnitTest.php | 4 ++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/WordPress/Sniffs/WP/AlternativeFunctionsSniff.php b/WordPress/Sniffs/WP/AlternativeFunctionsSniff.php index b773036576..9a0a2a9d03 100644 --- a/WordPress/Sniffs/WP/AlternativeFunctionsSniff.php +++ b/WordPress/Sniffs/WP/AlternativeFunctionsSniff.php @@ -353,7 +353,9 @@ public function process_matched_token( $stackPtr, $group_name, $matched_content */ protected function is_local_data_stream( $clean_param_value ) { - $stripped = TextStrings::stripQuotes( $clean_param_value ); + $stripped = TextStrings::stripQuotes( $clean_param_value ); + $clean_param_value = ltrim( $clean_param_value, '\\' ); + if ( isset( $this->allowed_local_streams[ $stripped ] ) || isset( $this->allowed_local_stream_constants[ $clean_param_value ] ) ) { diff --git a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc index 067178fb7a..70b67b1071 100644 --- a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc +++ b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc @@ -167,3 +167,16 @@ file_get_contents( $this?->plugin_dir_path() . 'subdir/file.inc' ); file_get_contents( MyClass::ABSPATH . 'subdir/file.inc' ); file_get_contents( $this->WPMU_PLUGIN_DIR . 'subdir/file.inc' ); file_get_contents( $this?->TEMPLATEPATH . 'subdir/file.inc' ); + +/* + * Safeguard correct handling of namespaced variants of STDIN/STDOUT/STDERR constants. + * + * Note: passing stream resources to these functions is not valid PHP and will be addressed in + * https://github.com/WordPress/WordPress-Coding-Standards/issues/2602. These tests document the current behavior of the + * sniff. + */ +fopen( \STDIN, 'r' ); +file_put_contents( MyNamespace\STDOUT, $data ); +file_get_contents( \MyNamespace\STDIN ); +file_put_contents( namespace\STDERR, $data ); // The sniff should not flag this once it can resolve relative namespaces. +readfile( namespace\Sub\STDIN ); diff --git a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php index 7aa4dccbb9..58f4083729 100644 --- a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php +++ b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php @@ -96,6 +96,10 @@ public function getWarningList() { 167 => 1, 168 => 1, 169 => 1, + 179 => 1, + 180 => 1, + 181 => 1, + 182 => 1, ); } }