These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * PHPCompatibility_Sniffs_PHP_PregReplaceEModifierSniff. |
||
| 4 | * |
||
| 5 | * PHP version 5.6 |
||
| 6 | * |
||
| 7 | * @category PHP |
||
| 8 | * @package PHPCompatibility |
||
| 9 | * @author Wim Godden <[email protected]> |
||
| 10 | * @copyright 2014 Cu.be Solutions bvba |
||
| 11 | */ |
||
| 12 | |||
| 13 | /** |
||
| 14 | * PHPCompatibility_Sniffs_PHP_PregReplaceEModifierSniff. |
||
| 15 | * |
||
| 16 | * @category PHP |
||
| 17 | * @package PHPCompatibility |
||
| 18 | * @author Wim Godden <[email protected]> |
||
| 19 | * @version 1.1.0 |
||
| 20 | * @copyright 2014 Cu.be Solutions bvba |
||
| 21 | */ |
||
| 22 | class PHPCompatibility_Sniffs_PHP_PregReplaceEModifierSniff extends PHPCompatibility_Sniff |
||
| 23 | { |
||
| 24 | |||
| 25 | /** |
||
| 26 | * Functions to check for. |
||
| 27 | * |
||
| 28 | * @var array |
||
| 29 | */ |
||
| 30 | protected $functions = array( |
||
| 31 | 'preg_replace' => true, |
||
| 32 | 'preg_filter' => true, |
||
| 33 | ); |
||
| 34 | |||
| 35 | /** |
||
| 36 | * Regex bracket delimiters. |
||
| 37 | * |
||
| 38 | * @var array |
||
| 39 | */ |
||
| 40 | protected $doublesSeparators = array( |
||
| 41 | '{' => '}', |
||
| 42 | '[' => ']', |
||
| 43 | '(' => ')', |
||
| 44 | '<' => '>', |
||
| 45 | ); |
||
| 46 | |||
| 47 | /** |
||
| 48 | * Returns an array of tokens this test wants to listen for. |
||
| 49 | * |
||
| 50 | * @return array |
||
| 51 | */ |
||
| 52 | public function register() |
||
| 53 | { |
||
| 54 | return array(T_STRING); |
||
| 55 | }//end register() |
||
| 56 | |||
| 57 | /** |
||
| 58 | * Processes this test, when one of its tokens is encountered. |
||
| 59 | * |
||
| 60 | * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. |
||
| 61 | * @param int $stackPtr The position of the current token in the |
||
| 62 | * stack passed in $tokens. |
||
| 63 | * |
||
| 64 | * @return void |
||
| 65 | */ |
||
| 66 | public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) |
||
| 67 | { |
||
| 68 | if ($this->supportsAbove('5.5') === false) { |
||
| 69 | return; |
||
| 70 | } |
||
| 71 | |||
| 72 | $tokens = $phpcsFile->getTokens(); |
||
| 73 | $functionName = $tokens[$stackPtr]['content']; |
||
| 74 | $functionNameLc = strtolower($functionName); |
||
| 75 | |||
| 76 | // Bow out if not one of the functions we're targetting. |
||
| 77 | if ( isset($this->functions[$functionNameLc]) === false ) { |
||
| 78 | return; |
||
| 79 | } |
||
| 80 | |||
| 81 | // Get the first parameter in the function call as that should contain the regex(es). |
||
| 82 | $firstParam = $this->getFunctionCallParameter($phpcsFile, $stackPtr, 1); |
||
| 83 | if ($firstParam === false) { |
||
| 84 | return; |
||
| 85 | } |
||
| 86 | |||
| 87 | // Differentiate between an array of patterns passed and a single pattern. |
||
| 88 | $nextNonEmpty = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $firstParam['start'], ($firstParam['end'] +1), true); |
||
| 89 | if ($tokens[$nextNonEmpty]['code'] === T_ARRAY || $tokens[$nextNonEmpty]['code'] === T_OPEN_SHORT_ARRAY) { |
||
| 90 | $arrayValues = $this->getFunctionCallParameters($phpcsFile, $nextNonEmpty); |
||
|
0 ignored issues
–
show
|
|||
| 91 | foreach ($arrayValues as $value) { |
||
| 92 | $hasKey = $phpcsFile->findNext(T_DOUBLE_ARROW, $value['start'], ($value['end'] + 1)); |
||
| 93 | if ($hasKey !== false) { |
||
| 94 | $value['start'] = ($hasKey + 1); |
||
| 95 | $value['raw'] = trim($phpcsFile->getTokensAsString($value['start'], (($value['end'] + 1) - $value['start']))); |
||
| 96 | } |
||
| 97 | |||
| 98 | $this->processRegexPattern($value, $phpcsFile, $value['end'], $functionName); |
||
| 99 | } |
||
| 100 | } |
||
| 101 | else { |
||
| 102 | $this->processRegexPattern($firstParam, $phpcsFile, $stackPtr, $functionName); |
||
| 103 | } |
||
| 104 | |||
| 105 | }//end process() |
||
| 106 | |||
| 107 | |||
| 108 | /** |
||
| 109 | * Analyse a potential regex pattern for usage of the /e modifier. |
||
| 110 | * |
||
| 111 | * @param array $pattern Array containing the start and end token |
||
| 112 | * pointer of the potential regex pattern and |
||
| 113 | * the raw string value of the pattern. |
||
| 114 | * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. |
||
| 115 | * @param int $stackPtr The position of the current token in the |
||
| 116 | * stack passed in $tokens. |
||
| 117 | * @param string $functionName The function which contained the pattern. |
||
| 118 | * |
||
| 119 | * @return void |
||
| 120 | */ |
||
| 121 | protected function processRegexPattern($pattern, $phpcsFile, $stackPtr, $functionName) |
||
| 122 | { |
||
| 123 | $tokens = $phpcsFile->getTokens(); |
||
| 124 | |||
| 125 | /* |
||
| 126 | * The pattern might be build up of a combination of strings, variables |
||
| 127 | * and function calls. We are only concerned with the strings. |
||
| 128 | */ |
||
| 129 | $regex = ''; |
||
| 130 | for ($i = $pattern['start']; $i <= $pattern['end']; $i++ ) { |
||
| 131 | if (in_array($tokens[$i]['code'], PHP_CodeSniffer_Tokens::$stringTokens, true) === true) { |
||
| 132 | $regex .= $this->stripQuotes($tokens[$i]['content']); |
||
| 133 | } |
||
| 134 | } |
||
| 135 | // Deal with multi-line regexes which were broken up in several string tokens. |
||
| 136 | $regex = $this->stripQuotes($regex); |
||
| 137 | |||
| 138 | if ($regex === '') { |
||
| 139 | // No string token found in the first parameter, so skip it (e.g. if variable passed in). |
||
| 140 | return; |
||
| 141 | } |
||
| 142 | |||
| 143 | $regexFirstChar = substr($regex, 0, 1); |
||
| 144 | |||
| 145 | // Make sure that the character identified as the delimiter is valid. |
||
| 146 | // Otherwise, it is a false positive caused by the string concatenation. |
||
| 147 | if (preg_match('`[a-z0-9\\\\ ]`i', $regexFirstChar) === 1) { |
||
| 148 | return; |
||
| 149 | } |
||
| 150 | |||
| 151 | if (isset($this->doublesSeparators[$regexFirstChar])) { |
||
| 152 | $regexEndPos = strrpos($regex, $this->doublesSeparators[$regexFirstChar]); |
||
| 153 | } |
||
| 154 | else { |
||
| 155 | $regexEndPos = strrpos($regex, $regexFirstChar); |
||
| 156 | } |
||
| 157 | |||
| 158 | if($regexEndPos) { |
||
| 159 | $modifiers = substr($regex, $regexEndPos + 1); |
||
| 160 | |||
| 161 | if (strpos($modifiers, 'e') !== false) { |
||
| 162 | $error = '%s() - /e modifier is deprecated since PHP 5.5'; |
||
| 163 | $isError = false; |
||
| 164 | $errorCode = 'Deprecated'; |
||
| 165 | $data = array($functionName); |
||
| 166 | |||
| 167 | if ($this->supportsAbove('7.0')) { |
||
| 168 | $error .= ' and removed since PHP 7.0'; |
||
| 169 | $isError = true; |
||
| 170 | $errorCode = 'Removed'; |
||
| 171 | } |
||
| 172 | |||
| 173 | $this->addMessage($phpcsFile, $error, $stackPtr, $isError, $errorCode, $data); |
||
| 174 | } |
||
| 175 | } |
||
| 176 | }//end processRegexPattern() |
||
| 177 | |||
| 178 | }//end class |
||
| 179 |
This check looks for type mismatches where the missing type is
false. This is usually indicative of an error condtion.Consider the follow example
This function either returns a new
DateTimeobject or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returnedfalsebefore passing on the value to another function or method that may not be able to handle afalse.