From 0db0767092aa865aef299bcb5cacb42373570969 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 15 May 2022 13:16:05 +0200 Subject: [PATCH 1/5] Move "array access keys" related utilities to dedicated `VariableHelper` The "array access keys" related utilities are only used by a small set of sniffs, so are better placed in a dedicated class. This commit moves the `get_array_access_keys()` method and the `get_array_access_key()` method to a new `WordPressCS\WordPress\Helpers\VariableHelper` and starts using that class in the relevant sniffs. In contrast to some of the other "move methods out of the Sniff class" PRs, these methods have been moved to a class and made `static` - instead of moved to a `trait`. The reason for this difference is that the methods in other "moves" are setting properties which the sniff classes would need access to, while these methods are 100% stand-alone. **Note**: It is expected for PHPCSUtils to have dedicated methods for the same at some point in the future. If/when those methods become available, it is recommended for the sniffs to start using the PHPCSUtils methods. With this in mind, this class has been marked as "internal" without BC promise. Related to 1465 --- WordPress/Helpers/VariableHelper.php | 113 ++++++++++++++++++ WordPress/Sniff.php | 83 +------------ .../Sniffs/Security/EscapeOutputSniff.php | 5 +- .../Security/ValidatedSanitizedInputSniff.php | 3 +- .../WP/GlobalVariablesOverrideSniff.php | 5 +- 5 files changed, 125 insertions(+), 84 deletions(-) create mode 100644 WordPress/Helpers/VariableHelper.php diff --git a/WordPress/Helpers/VariableHelper.php b/WordPress/Helpers/VariableHelper.php new file mode 100644 index 0000000000..60f7ffa422 --- /dev/null +++ b/WordPress/Helpers/VariableHelper.php @@ -0,0 +1,113 @@ +getTokens(); + $keys = array(); + + if ( \T_VARIABLE !== $tokens[ $stackPtr ]['code'] ) { + return $keys; + } + + $current = $stackPtr; + + do { + // Find the next non-empty token. + $open_bracket = $phpcsFile->findNext( + Tokens::$emptyTokens, + ( $current + 1 ), + null, + true + ); + + // If it isn't a bracket, this isn't an array-access. + if ( false === $open_bracket + || \T_OPEN_SQUARE_BRACKET !== $tokens[ $open_bracket ]['code'] + || ! isset( $tokens[ $open_bracket ]['bracket_closer'] ) + ) { + break; + } + + $key = $phpcsFile->getTokensAsString( + ( $open_bracket + 1 ), + ( $tokens[ $open_bracket ]['bracket_closer'] - $open_bracket - 1 ) + ); + + $keys[] = trim( $key ); + $current = $tokens[ $open_bracket ]['bracket_closer']; + } while ( isset( $tokens[ $current ] ) && true === $all ); + + return $keys; + } + + /** + * Get the index key of an array variable. + * + * E.g., "bar" in $foo['bar']. + * + * @since 0.5.0 + * @since 2.1.0 Now uses get_array_access_keys() under the hood. + * @since 3.0.0 - Moved from the Sniff class to this class. + * - Visibility is now `public` (was `protected`) and the method `static`. + * - The $phpcsFile parameter was added. + * + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. + * @param int $stackPtr The index of the token in the stack. + * + * @return string|false The array index key whose value is being accessed. + */ + public static function get_array_access_key( File $phpcsFile, $stackPtr ) { + $keys = self::get_array_access_keys( $phpcsFile, $stackPtr, false ); + if ( isset( $keys[0] ) ) { + return $keys[0]; + } + + return false; + } +} diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index 0e38885671..fa5dfd4720 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -16,6 +16,7 @@ use PHPCSUtils\Utils\PassedParameters; use PHPCSUtils\Utils\Scopes; use PHPCSUtils\Utils\TextStrings; +use WordPressCS\WordPress\Helpers\VariableHelper; /** * Represents a PHP_CodeSniffer sniff for sniffing WordPress coding standards. @@ -1613,82 +1614,6 @@ public function add_unslash_error( $stackPtr ) { ); } - /** - * Get the index keys of an array variable. - * - * E.g., "bar" and "baz" in $foo['bar']['baz']. - * - * @since 2.1.0 - * - * @param int $stackPtr The index of the variable token in the stack. - * @param bool $all Whether to get all keys or only the first. - * Defaults to `true`(= all). - * - * @return array An array of index keys whose value is being accessed. - * or an empty array if this is not array access. - */ - protected function get_array_access_keys( $stackPtr, $all = true ) { - - $keys = array(); - - if ( \T_VARIABLE !== $this->tokens[ $stackPtr ]['code'] ) { - return $keys; - } - - $current = $stackPtr; - - do { - // Find the next non-empty token. - $open_bracket = $this->phpcsFile->findNext( - Tokens::$emptyTokens, - ( $current + 1 ), - null, - true - ); - - // If it isn't a bracket, this isn't an array-access. - if ( false === $open_bracket - || \T_OPEN_SQUARE_BRACKET !== $this->tokens[ $open_bracket ]['code'] - || ! isset( $this->tokens[ $open_bracket ]['bracket_closer'] ) - ) { - break; - } - - $key = $this->phpcsFile->getTokensAsString( - ( $open_bracket + 1 ), - ( $this->tokens[ $open_bracket ]['bracket_closer'] - $open_bracket - 1 ) - ); - - $keys[] = trim( $key ); - $current = $this->tokens[ $open_bracket ]['bracket_closer']; - } while ( isset( $this->tokens[ $current ] ) && true === $all ); - - return $keys; - } - - /** - * Get the index key of an array variable. - * - * E.g., "bar" in $foo['bar']. - * - * @since 0.5.0 - * @since 2.1.0 Now uses get_array_access_keys() under the hood. - * - * @param int $stackPtr The index of the token in the stack. - * - * @return string|false The array index key whose value is being accessed. - */ - protected function get_array_access_key( $stackPtr ) { - - $keys = $this->get_array_access_keys( $stackPtr, false ); - - if ( isset( $keys[0] ) ) { - return $keys[0]; - } - - return false; - } - /** * Check if the existence of a variable is validated with isset(), empty(), array_key_exists() * or key_exists(). @@ -1826,7 +1751,7 @@ protected function is_validated( $stackPtr, $array_keys = array(), $in_condition // If we're checking for specific array keys (ex: 'hello' in // $_POST['hello']), that must match too. Quote-style, however, doesn't matter. if ( ! empty( $bare_array_keys ) ) { - $found_keys = $this->get_array_access_keys( $i ); + $found_keys = VariableHelper::get_array_access_keys( $this->phpcsFile, $i ); $found_keys = array_map( array( 'PHPCSUtils\Utils\TextStrings', 'stripQuotes' ), $found_keys ); $diff = array_diff_assoc( $bare_array_keys, $found_keys ); if ( ! empty( $diff ) ) { @@ -1887,7 +1812,7 @@ protected function is_validated( $stackPtr, $array_keys = array(), $in_condition * parameter, so we need to check both options. */ - $found_keys = $this->get_array_access_keys( $param2_first_token ); + $found_keys = VariableHelper::get_array_access_keys( $this->phpcsFile, $param2_first_token ); $found_keys = array_map( array( 'PHPCSUtils\Utils\TextStrings', 'stripQuotes' ), $found_keys ); // First try matching the complete set against the second parameter. @@ -1931,7 +1856,7 @@ protected function is_validated( $stackPtr, $array_keys = array(), $in_condition } if ( ! empty( $bare_array_keys ) ) { - $found_keys = $this->get_array_access_keys( $prev ); + $found_keys = VariableHelper::get_array_access_keys( $this->phpcsFile, $prev ); $found_keys = array_map( array( 'PHPCSUtils\Utils\TextStrings', 'stripQuotes' ), $found_keys ); $diff = array_diff_assoc( $bare_array_keys, $found_keys ); if ( ! empty( $diff ) ) { diff --git a/WordPress/Sniffs/Security/EscapeOutputSniff.php b/WordPress/Sniffs/Security/EscapeOutputSniff.php index 09cd206ff3..ce686ac05d 100644 --- a/WordPress/Sniffs/Security/EscapeOutputSniff.php +++ b/WordPress/Sniffs/Security/EscapeOutputSniff.php @@ -9,10 +9,11 @@ namespace WordPressCS\WordPress\Sniffs\Security; -use WordPressCS\WordPress\Sniff; use PHP_CodeSniffer\Util\Tokens; use PHPCSUtils\Utils\PassedParameters; use PHPCSUtils\Utils\TextStrings; +use WordPressCS\WordPress\Helpers\VariableHelper; +use WordPressCS\WordPress\Sniff; /** * Verifies that all outputted strings are escaped. @@ -452,7 +453,7 @@ public function process_token( $stackPtr ) { // Make the error message a little more informative for array access variables. if ( \T_VARIABLE === $this->tokens[ $ptr ]['code'] ) { - $array_keys = $this->get_array_access_keys( $ptr ); + $array_keys = VariableHelper::get_array_access_keys( $this->phpcsFile, $ptr ); if ( ! empty( $array_keys ) ) { $content .= '[' . implode( '][', $array_keys ) . ']'; diff --git a/WordPress/Sniffs/Security/ValidatedSanitizedInputSniff.php b/WordPress/Sniffs/Security/ValidatedSanitizedInputSniff.php index 00289b07bd..1e1847fbb5 100644 --- a/WordPress/Sniffs/Security/ValidatedSanitizedInputSniff.php +++ b/WordPress/Sniffs/Security/ValidatedSanitizedInputSniff.php @@ -11,6 +11,7 @@ use PHP_CodeSniffer\Util\Tokens; use WordPressCS\WordPress\Helpers\TextStringHelper; +use WordPressCS\WordPress\Helpers\VariableHelper; use WordPressCS\WordPress\Sniff; /** @@ -125,7 +126,7 @@ function ( $symbol ) { return; } - $array_keys = $this->get_array_access_keys( $stackPtr ); + $array_keys = VariableHelper::get_array_access_keys( $this->phpcsFile, $stackPtr ); if ( empty( $array_keys ) ) { return; diff --git a/WordPress/Sniffs/WP/GlobalVariablesOverrideSniff.php b/WordPress/Sniffs/WP/GlobalVariablesOverrideSniff.php index d07064c489..0ab1bcd1d5 100644 --- a/WordPress/Sniffs/WP/GlobalVariablesOverrideSniff.php +++ b/WordPress/Sniffs/WP/GlobalVariablesOverrideSniff.php @@ -13,8 +13,9 @@ use PHPCSUtils\Utils\Lists; use PHPCSUtils\Utils\Scopes; use PHPCSUtils\Utils\TextStrings; -use WordPressCS\WordPress\Sniff; use WordPressCS\WordPress\Helpers\IsUnitTestTrait; +use WordPressCS\WordPress\Helpers\VariableHelper; +use WordPressCS\WordPress\Sniff; /** * Warns about overwriting WordPress native global variables. @@ -384,7 +385,7 @@ protected function process_global_statement( $stackPtr, $in_function_scope ) { foreach ( $var_pointers as $ptr ) { $var_name = $this->tokens[ $ptr ]['content']; if ( '$GLOBALS' === $var_name ) { - $var_name = '$' . TextStrings::stripQuotes( $this->get_array_access_key( $ptr ) ); + $var_name = '$' . TextStrings::stripQuotes( VariableHelper::get_array_access_key( $this->phpcsFile, $ptr ) ); } if ( \in_array( $var_name, $search, true ) ) { From 8d3bb6fd44d6db98d6e80923371659c9ae353bc4 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 15 May 2022 13:30:23 +0200 Subject: [PATCH 2/5] VariableHelper::get_array_access_keys() use PHPCSUtils Use the PHPCSUtils `GetTokensAsString::compact()` method to retrieve array access keys without extraneous whitespace or comments. --- WordPress/Helpers/VariableHelper.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/WordPress/Helpers/VariableHelper.php b/WordPress/Helpers/VariableHelper.php index 60f7ffa422..de12ac98f2 100644 --- a/WordPress/Helpers/VariableHelper.php +++ b/WordPress/Helpers/VariableHelper.php @@ -11,6 +11,7 @@ use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; +use PHPCSUtils\Utils\GetTokensAsString; /** * Helper utilities for working with variables representing arrays. @@ -74,9 +75,11 @@ public static function get_array_access_keys( File $phpcsFile, $stackPtr, $all = break; } - $key = $phpcsFile->getTokensAsString( + $key = GetTokensAsString::compact( + $phpcsFile, ( $open_bracket + 1 ), - ( $tokens[ $open_bracket ]['bracket_closer'] - $open_bracket - 1 ) + ( $tokens[ $open_bracket ]['bracket_closer'] - 1 ), + true ); $keys[] = trim( $key ); From bb5822a1866506eb7959f9e3d635bfa7872c09a3 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 15 May 2022 13:43:19 +0200 Subject: [PATCH 3/5] Move "is comparison" related utility to dedicated `VariableHelper` The "is comparison" related utility method is only used by a small set of sniffs, so is better placed in a dedicated class. As this method also expects a `T_VARIABLE` token as input, the `VariableHelper` class seems appropriate. This commit moves the `is_comparison()` method to the new `WordPressCS\WordPress\Helpers\VariableHelper` and starts using that class in the relevant sniffs. **Note**: It is expected for PHPCSUtils to have dedicated methods for the same at some point in the future. If/when those methods become available, it is recommended for the sniffs to start using the PHPCSUtils methods. Related to 1465 --- WordPress/Helpers/VariableHelper.php | 75 ++++++++++++++++- WordPress/Sniff.php | 81 +------------------ .../Security/ValidatedSanitizedInputSniff.php | 2 +- 3 files changed, 76 insertions(+), 82 deletions(-) diff --git a/WordPress/Helpers/VariableHelper.php b/WordPress/Helpers/VariableHelper.php index de12ac98f2..4714b066b9 100644 --- a/WordPress/Helpers/VariableHelper.php +++ b/WordPress/Helpers/VariableHelper.php @@ -14,7 +14,7 @@ use PHPCSUtils\Utils\GetTokensAsString; /** - * Helper utilities for working with variables representing arrays. + * Helper utilities for working with variables. * * --------------------------------------------------------------------------------------------- * This class is only intended for internal use by WordPressCS and is not part of the public API. @@ -113,4 +113,77 @@ public static function get_array_access_key( File $phpcsFile, $stackPtr ) { return false; } + + /** + * Check whether a variable is being compared to another value. + * + * E.g., $var === 'foo', 1 <= $var, etc. + * + * Also recognizes `switch ( $var )`. + * + * @since 0.5.0 + * @since 2.1.0 Added the $include_coalesce parameter. + * @since 3.0.0 - Moved from the Sniff class to this class. + * - Visibility is now `public` (was `protected`) and the method `static`. + * - The $phpcsFile parameter was added. + * + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. + * @param int $stackPtr The index of this token in the stack. + * @param bool $include_coalesce Optional. Whether or not to regard the null + * coalesce operator - ?? - as a comparison operator. + * Defaults to true. + * Null coalesce is a special comparison operator in this + * sense as it doesn't compare a variable to whatever is + * on the other side of the comparison operator. + * + * @return bool Whether this is a comparison. + */ + public static function is_comparison( File $phpcsFile, $stackPtr, $include_coalesce = true ) { + $tokens = $phpcsFile->getTokens(); + $comparisonTokens = Tokens::$comparisonTokens; + if ( false === $include_coalesce ) { + unset( $comparisonTokens[ \T_COALESCE ] ); + } + + // We first check if this is a switch statement (switch ( $var )). + if ( isset( $tokens[ $stackPtr ]['nested_parenthesis'] ) ) { + $nested_parenthesis = $tokens[ $stackPtr ]['nested_parenthesis']; + $close_parenthesis = end( $nested_parenthesis ); + + if ( + isset( $tokens[ $close_parenthesis ]['parenthesis_owner'] ) + && \T_SWITCH === $tokens[ $tokens[ $close_parenthesis ]['parenthesis_owner'] ]['code'] + ) { + return true; + } + } + + // Find the previous non-empty token. We check before the var first because + // yoda conditions are usually expected. + $previous_token = $phpcsFile->findPrevious( Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true ); + + if ( isset( $comparisonTokens[ $tokens[ $previous_token ]['code'] ] ) ) { + return true; + } + + // Maybe the comparison operator is after this. + $next_token = $phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); + + // This might be an opening square bracket in the case of arrays ($var['a']). + while ( false !== $next_token && \T_OPEN_SQUARE_BRACKET === $tokens[ $next_token ]['code'] ) { + + $next_token = $phpcsFile->findNext( + Tokens::$emptyTokens, + ( $tokens[ $next_token ]['bracket_closer'] + 1 ), + null, + true + ); + } + + if ( false !== $next_token && isset( $comparisonTokens[ $tokens[ $next_token ]['code'] ] ) ) { + return true; + } + + return false; + } } diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index fa5dfd4720..c54d6c23c4 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -1124,7 +1124,7 @@ protected function has_nonce_check( $stackPtr ) { $allow_nonce_after = false; if ( $this->is_in_isset_or_empty( $stackPtr ) || $this->is_in_type_test( $stackPtr ) - || $this->is_comparison( $stackPtr ) + || VariableHelper::is_comparison( $this->phpcsFile, $stackPtr ) || $this->is_in_array_comparison( $stackPtr ) || $this->is_in_function_call( $stackPtr, $this->unslashingFunctions ) !== false || $this->is_only_sanitized( $stackPtr ) @@ -1872,85 +1872,6 @@ protected function is_validated( $stackPtr, $array_keys = array(), $in_condition return false; } - /** - * Check whether a variable is being compared to another value. - * - * E.g., $var === 'foo', 1 <= $var, etc. - * - * Also recognizes `switch ( $var )`. - * - * @since 0.5.0 - * @since 2.1.0 Added the $include_coalesce parameter. - * - * @param int $stackPtr The index of this token in the stack. - * @param bool $include_coalesce Optional. Whether or not to regard the null - * coalesce operator - ?? - as a comparison operator. - * Defaults to true. - * Null coalesce is a special comparison operator in this - * sense as it doesn't compare a variable to whatever is - * on the other side of the comparison operator. - * - * @return bool Whether this is a comparison. - */ - protected function is_comparison( $stackPtr, $include_coalesce = true ) { - - $comparisonTokens = Tokens::$comparisonTokens; - if ( false === $include_coalesce ) { - unset( $comparisonTokens[ \T_COALESCE ] ); - } - - // We first check if this is a switch statement (switch ( $var )). - if ( isset( $this->tokens[ $stackPtr ]['nested_parenthesis'] ) ) { - $nested_parenthesis = $this->tokens[ $stackPtr ]['nested_parenthesis']; - $close_parenthesis = end( $nested_parenthesis ); - - if ( - isset( $this->tokens[ $close_parenthesis ]['parenthesis_owner'] ) - && \T_SWITCH === $this->tokens[ $this->tokens[ $close_parenthesis ]['parenthesis_owner'] ]['code'] - ) { - return true; - } - } - - // Find the previous non-empty token. We check before the var first because - // yoda conditions are usually expected. - $previous_token = $this->phpcsFile->findPrevious( - Tokens::$emptyTokens, - ( $stackPtr - 1 ), - null, - true - ); - - if ( isset( $comparisonTokens[ $this->tokens[ $previous_token ]['code'] ] ) ) { - return true; - } - - // Maybe the comparison operator is after this. - $next_token = $this->phpcsFile->findNext( - Tokens::$emptyTokens, - ( $stackPtr + 1 ), - null, - true - ); - - // This might be an opening square bracket in the case of arrays ($var['a']). - while ( false !== $next_token && \T_OPEN_SQUARE_BRACKET === $this->tokens[ $next_token ]['code'] ) { - - $next_token = $this->phpcsFile->findNext( - Tokens::$emptyTokens, - ( $this->tokens[ $next_token ]['bracket_closer'] + 1 ), - null, - true - ); - } - - if ( false !== $next_token && isset( $comparisonTokens[ $this->tokens[ $next_token ]['code'] ] ) ) { - return true; - } - - return false; - } - /** * Check if a token is inside of an array-value comparison function. * diff --git a/WordPress/Sniffs/Security/ValidatedSanitizedInputSniff.php b/WordPress/Sniffs/Security/ValidatedSanitizedInputSniff.php index 1e1847fbb5..d3810ff68e 100644 --- a/WordPress/Sniffs/Security/ValidatedSanitizedInputSniff.php +++ b/WordPress/Sniffs/Security/ValidatedSanitizedInputSniff.php @@ -179,7 +179,7 @@ function ( $symbol ) { } // If this is a comparison ('a' == $_POST['foo']), sanitization isn't needed. - if ( $this->is_comparison( $stackPtr, false ) ) { + if ( VariableHelper::is_comparison( $this->phpcsFile, $stackPtr, false ) ) { return; } From 54d6474045145a1678c529f4e31233c4f11d2ea5 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 15 May 2022 13:54:00 +0200 Subject: [PATCH 4/5] VariableHelper::is_comparison(): use PHPCSUtils ... to get the potential parentheses opener. --- WordPress/Helpers/VariableHelper.php | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/WordPress/Helpers/VariableHelper.php b/WordPress/Helpers/VariableHelper.php index 4714b066b9..7c47660d69 100644 --- a/WordPress/Helpers/VariableHelper.php +++ b/WordPress/Helpers/VariableHelper.php @@ -12,6 +12,7 @@ use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; use PHPCSUtils\Utils\GetTokensAsString; +use PHPCSUtils\Utils\Parentheses; /** * Helper utilities for working with variables. @@ -146,16 +147,8 @@ public static function is_comparison( File $phpcsFile, $stackPtr, $include_coale } // We first check if this is a switch statement (switch ( $var )). - if ( isset( $tokens[ $stackPtr ]['nested_parenthesis'] ) ) { - $nested_parenthesis = $tokens[ $stackPtr ]['nested_parenthesis']; - $close_parenthesis = end( $nested_parenthesis ); - - if ( - isset( $tokens[ $close_parenthesis ]['parenthesis_owner'] ) - && \T_SWITCH === $tokens[ $tokens[ $close_parenthesis ]['parenthesis_owner'] ]['code'] - ) { - return true; - } + if ( Parentheses::lastOwnerIn( $phpcsFile, $stackPtr, array( \T_SWITCH ) ) !== false ) { + return true; } // Find the previous non-empty token. We check before the var first because From c592999c8dbf8ae25f47c9314fdef90ab653bdd6 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 15 May 2022 14:03:29 +0200 Subject: [PATCH 5/5] PHP 8.0 | VariableHelper::is_comparison(): add support for variables being compared in a `match` expression PHP 8.0 introduced `match` expressions, which do a (strict) comparison on the value in the condition against the options in the `match` body. Ref: https://www.php.net/manual/en/control-structures.match.php This commit updates the `is_comparison()` method to allow for variables in the "condition" part of a `match` expression to be considered part of a comparison. Tested via the `ValidatedSanitizedInput` sniff. --- WordPress/Helpers/VariableHelper.php | 6 +++--- .../Tests/Security/ValidatedSanitizedInputUnitTest.inc | 3 +++ .../Tests/Security/ValidatedSanitizedInputUnitTest.php | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/WordPress/Helpers/VariableHelper.php b/WordPress/Helpers/VariableHelper.php index 7c47660d69..a1a5e46362 100644 --- a/WordPress/Helpers/VariableHelper.php +++ b/WordPress/Helpers/VariableHelper.php @@ -120,7 +120,7 @@ public static function get_array_access_key( File $phpcsFile, $stackPtr ) { * * E.g., $var === 'foo', 1 <= $var, etc. * - * Also recognizes `switch ( $var )`. + * Also recognizes `switch ( $var )` and `match ( $var )`. * * @since 0.5.0 * @since 2.1.0 Added the $include_coalesce parameter. @@ -146,8 +146,8 @@ public static function is_comparison( File $phpcsFile, $stackPtr, $include_coale unset( $comparisonTokens[ \T_COALESCE ] ); } - // We first check if this is a switch statement (switch ( $var )). - if ( Parentheses::lastOwnerIn( $phpcsFile, $stackPtr, array( \T_SWITCH ) ) !== false ) { + // We first check if this is a switch or match statement (switch ( $var )). + if ( Parentheses::lastOwnerIn( $phpcsFile, $stackPtr, array( \T_SWITCH, \T_MATCH ) ) !== false ) { return true; } diff --git a/WordPress/Tests/Security/ValidatedSanitizedInputUnitTest.inc b/WordPress/Tests/Security/ValidatedSanitizedInputUnitTest.inc index 12f9f65309..f5d5dd6e07 100644 --- a/WordPress/Tests/Security/ValidatedSanitizedInputUnitTest.inc +++ b/WordPress/Tests/Security/ValidatedSanitizedInputUnitTest.inc @@ -333,3 +333,6 @@ function test_using_different_unslashing_functions() { } echo wp_sanitize_redirect( wp_unslash( $_GET['test'] ) ); // OK. + +$result = match ( $_POST['foo'] ) {}; // Ok. +$result = match ( do_something( wp_unslash( $_POST['foo'] ) ) ) {}; // Bad. diff --git a/WordPress/Tests/Security/ValidatedSanitizedInputUnitTest.php b/WordPress/Tests/Security/ValidatedSanitizedInputUnitTest.php index 8643c2a78d..ac41f98ad2 100644 --- a/WordPress/Tests/Security/ValidatedSanitizedInputUnitTest.php +++ b/WordPress/Tests/Security/ValidatedSanitizedInputUnitTest.php @@ -80,6 +80,7 @@ public function getErrorList() { 315 => 2, 317 => 1, 323 => 1, + 338 => 1, ); }