This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * CodeIgniter_Sniffs_Strings_DoubleQuoteUsageSniff. |
||
5 | * |
||
6 | * PHP version 5 |
||
7 | * |
||
8 | * @category PHP |
||
9 | * @package PHP_CodeSniffer |
||
10 | * @author Thomas Ernest <[email protected]> |
||
11 | * @copyright 2011 Thomas Ernest |
||
12 | * @license http://thomas.ernest.fr/developement/php_cs/licence GNU General Public License |
||
13 | * @link http://pear.php.net/package/PHP_CodeSniffer |
||
14 | */ |
||
15 | |||
16 | namespace CodeIgniter\Sniffs\Strings; |
||
17 | |||
18 | use PHP_CodeSniffer\Sniffs\Sniff; |
||
19 | use PHP_CodeSniffer\Files\File; |
||
20 | |||
21 | /** |
||
22 | * CodeIgniter_Sniffs_Strings_DoubleQuoteUsageSniff. |
||
23 | * |
||
24 | * Ensures that double-quoted strings are used only to parse variables, |
||
25 | * to avoid escape characters before single quotes or for chars that need |
||
26 | * to be interpreted like \r, \n or \t. |
||
27 | * If a double-quoted string contain both single and double quotes |
||
28 | * but no variable, then a warning is raised to encourage the use of |
||
29 | * single-quoted strings. |
||
30 | * |
||
31 | * @category PHP |
||
32 | * @package PHP_CodeSniffer |
||
33 | * @author Thomas Ernest <[email protected]> |
||
34 | * @copyright 2011 Thomas Ernest |
||
35 | * @license http://thomas.ernest.fr/developement/php_cs/licence GNU General Public License |
||
36 | * @link http://pear.php.net/package/PHP_CodeSniffer |
||
37 | */ |
||
38 | class VariableUsageSniff implements Sniff |
||
39 | { |
||
40 | /** |
||
41 | * Returns an array of tokens this test wants to listen for. |
||
42 | * |
||
43 | * @return array |
||
44 | */ |
||
45 | public function register() |
||
46 | { |
||
47 | /* |
||
48 | return array( |
||
49 | T_DOUBLE_QUOTED_STRING, |
||
50 | T_CONSTANT_ENCAPSED_STRING, |
||
51 | ); |
||
52 | */ |
||
53 | return array(); |
||
54 | }//end register() |
||
55 | |||
56 | |||
57 | /** |
||
58 | * Processes this test, when one of its tokens is encountered. |
||
59 | * |
||
60 | * @param File $phpcsFile The current file being scanned. |
||
61 | * @param int $stackPtr The position of the current token |
||
62 | * in the stack passed in $tokens. |
||
63 | * |
||
64 | * @return void |
||
65 | */ |
||
66 | public function process(File $phpcsFile, $stackPtr) |
||
67 | { |
||
68 | $tokens = $phpcsFile->getTokens(); |
||
69 | $string = $tokens[$stackPtr]['content']; |
||
70 | // makes sure that it is about a double quote string, |
||
71 | // since variables are not parsed out of double quoted string |
||
72 | $openDblQtStr = substr($string, 0, 1); |
||
73 | View Code Duplication | if (0 === strcmp($openDblQtStr, '"')) { |
|
0 ignored issues
–
show
|
|||
74 | $this->processDoubleQuotedString($phpcsFile, $stackPtr, $string); |
||
75 | } else if (0 === strcmp($openDblQtStr, "'")) { |
||
76 | $this->processSingleQuotedString($phpcsFile, $stackPtr, $string); |
||
77 | } |
||
78 | }//end process() |
||
79 | |||
80 | |||
81 | /** |
||
82 | * Processes this test, when the token encountered is a double-quoted string. |
||
83 | * |
||
84 | * @param File $phpcsFile The current file being scanned. |
||
85 | * @param int $stackPtr The position of the current token |
||
86 | * in the stack passed in $tokens. |
||
87 | * @param string $dblQtString The double-quoted string content, |
||
88 | * i.e. without quotes. |
||
89 | * |
||
90 | * @return void |
||
0 ignored issues
–
show
|
|||
91 | */ |
||
92 | protected function processDoubleQuotedString (File $phpcsFile, $stackPtr, $dblQtString) |
||
93 | { |
||
94 | $variableFound = FALSE; |
||
95 | $strTokens = token_get_all('<?php '.$dblQtString); |
||
96 | $strPtr = 1; // skip php opening tag added by ourselves |
||
97 | $requireDblQuotes = FALSE; |
||
98 | while ($strPtr < count($strTokens)) { |
||
99 | $strToken = $strTokens[$strPtr]; |
||
100 | if (is_array($strToken)) { |
||
101 | if (in_array($strToken[0], array(T_DOLLAR_OPEN_CURLY_BRACES, T_CURLY_OPEN))) { |
||
102 | $strPtr++; |
||
103 | try { |
||
104 | $this->_parseVariable($strTokens, $strPtr); |
||
105 | } catch (Exception $err) { |
||
106 | $error = 'There is no variable, object nor array between curly braces. Please use the escape char for $ or {.'; |
||
107 | $phpcsFile->addError($error, $stackPtr); |
||
108 | } |
||
109 | $variableFound = TRUE; |
||
110 | if ('}' !== $strTokens[$strPtr]) { |
||
111 | $error = 'There is no matching closing curly brace.'; |
||
112 | $phpcsFile->addError($error, $stackPtr); |
||
113 | } |
||
114 | // don't move forward, since it will be done in the main loop |
||
115 | // $strPtr++; |
||
116 | View Code Duplication | } else if (T_VARIABLE === $strToken[0]) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
117 | $variableFound = TRUE; |
||
118 | $error = "Variable {$strToken[1]} in double-quoted strings should be enclosed with curly braces. Please consider {{$strToken[1]}}"; |
||
119 | $phpcsFile->addError($error, $stackPtr); |
||
120 | } |
||
121 | } |
||
122 | $strPtr++; |
||
123 | } |
||
124 | return $variableFound; |
||
125 | }//end processDoubleQuotedString() |
||
126 | |||
127 | |||
128 | /** |
||
129 | * Processes this test, when the token encountered is a single-quoted string. |
||
130 | * |
||
131 | * @param File $phpcsFile The current file being scanned. |
||
132 | * @param int $stackPtr The position of the current token |
||
133 | * in the stack passed in $tokens. |
||
134 | * @param string $sglQtString The single-quoted string content, |
||
135 | * i.e. without quotes. |
||
136 | * |
||
137 | * @return void |
||
0 ignored issues
–
show
|
|||
138 | */ |
||
139 | protected function processSingleQuotedString (File $phpcsFile, $stackPtr, $sglQtString) |
||
140 | { |
||
141 | $variableFound = FALSE; |
||
142 | $strTokens = token_get_all('<?php '.$sglQtString); |
||
143 | $strPtr = 1; // skip php opening tag added by ourselves |
||
144 | while ($strPtr < count($strTokens)) { |
||
145 | $strToken = $strTokens[$strPtr]; |
||
146 | View Code Duplication | if (is_array($strToken)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
147 | if (T_VARIABLE === $strToken[0]) { |
||
148 | $error = "Variables like {$strToken[1]} should be in double-quoted strings only."; |
||
149 | $phpcsFile->addError($error, $stackPtr); |
||
150 | } |
||
151 | } |
||
152 | $strPtr++; |
||
153 | } |
||
154 | return $variableFound; |
||
155 | }//end processSingleQuotedString() |
||
156 | |||
157 | /** |
||
158 | * Grammar rule to parse the use of a variable. Please notice that it |
||
159 | * doesn't manage the leading $. |
||
160 | * |
||
161 | * _parseVariable ::= <variable> |
||
162 | * | <variable>_parseObjectAttribute() |
||
163 | * | <variable>_parseArrayIndexes() |
||
164 | * |
||
165 | * @exception Exception raised if $strTokens starting from $strPtr |
||
166 | * doesn't matched the rule. |
||
167 | * |
||
168 | * @param array $strTokens Tokens to parse. |
||
169 | * @param int $strPtr Pointer to the token where parsing starts. |
||
170 | * |
||
171 | * @return array The attribute name associated to index 'var', an array with |
||
172 | * indexes 'obj' and 'attr' or an array with indexes 'arr' and 'idx'. |
||
173 | */ |
||
174 | private function _parseVariable ($strTokens, &$strPtr) |
||
175 | { |
||
176 | if ( ! in_array($strTokens[$strPtr][0], array(T_VARIABLE, T_STRING_VARNAME))) { |
||
177 | throw new Exception ('Expected variable name.'); |
||
178 | } |
||
179 | $var = $strTokens[$strPtr][1]; |
||
180 | $strPtr++; |
||
181 | $startStrPtr = $strPtr; |
||
182 | try { |
||
183 | $attr = $this->_parseObjectAttribute($strTokens, $strPtr); |
||
184 | return array ('obj' => $var, 'attr' => $attr); |
||
185 | } catch (Exception $err) { |
||
186 | if ($strPtr !== $startStrPtr) { |
||
187 | throw $err; |
||
188 | } |
||
189 | } |
||
190 | try { |
||
191 | $idx = $this->_parseArrayIndexes($strTokens, $strPtr); |
||
192 | return array ('arr' => $var, 'idx' => $idx); |
||
193 | } catch (Exception $err) { |
||
194 | if ($strPtr !== $startStrPtr) { |
||
195 | throw $err; |
||
196 | } |
||
197 | } |
||
198 | return array ('var' => $var); |
||
199 | }//end _parseVariable() |
||
200 | |||
201 | |||
202 | /** |
||
203 | * Grammar rule to parse the use of an object attribute. |
||
204 | * |
||
205 | * _parseObjectAttribute ::= -><attribute> |
||
206 | * | -><attribute>_parseObjectAttribute() |
||
207 | * | -><attribute>_parseArrayIndexes() |
||
208 | * |
||
209 | * @exception Exception raised if $strTokens starting from $strPtr |
||
210 | * doesn't matched the rule. |
||
211 | * |
||
212 | * @param array $strTokens Tokens to parse. |
||
213 | * @param int $strPtr Pointer to the token where parsing starts. |
||
214 | * |
||
215 | * @return mixed The attribute name as a string, an array with indexes |
||
216 | * 'obj' and 'attr' or an array with indexes 'arr' and 'idx'. |
||
217 | */ |
||
218 | private function _parseObjectAttribute ($strTokens, &$strPtr) |
||
219 | { |
||
220 | if (T_OBJECT_OPERATOR !== $strTokens[$strPtr][0]) { |
||
221 | throw new Exception ('Expected ->.'); |
||
222 | } |
||
223 | $strPtr++; |
||
224 | if (T_STRING !== $strTokens[$strPtr][0]) { |
||
225 | throw new Exception ('Expected an object attribute.'); |
||
226 | } |
||
227 | $attr = $strTokens[$strPtr][1]; |
||
228 | $strPtr++; |
||
229 | $startStrPtr = $strPtr; |
||
230 | try { |
||
231 | $sub_attr = $this->_parseObjectAttribute($strTokens, $strPtr); |
||
232 | return array ('obj' => $attr, 'attr' => $sub_attr); |
||
233 | } catch (Exception $err) { |
||
234 | if ($strPtr !== $startStrPtr) { |
||
235 | throw $err; |
||
236 | } |
||
237 | } |
||
238 | try { |
||
239 | $idx = $this->_parseArrayIndexes($strTokens, $strPtr); |
||
240 | return array ('arr' => $attr, 'idx' => $idx); |
||
241 | } catch (Exception $err) { |
||
242 | if ($strPtr !== $startStrPtr) { |
||
243 | throw $err; |
||
244 | } |
||
245 | } |
||
246 | return $attr; |
||
247 | }//end _parseObjectAttribute() |
||
248 | |||
249 | |||
250 | /** |
||
251 | * Grammar rule to parse the use of one or more array indexes. |
||
252 | * |
||
253 | * _parseArrayIndexes ::= _parseArrayIndex()+ |
||
254 | * |
||
255 | * @exception Exception raised if $strTokens starting from $strPtr |
||
256 | * doesn't matched the rule. |
||
257 | * |
||
258 | * @param array $strTokens Tokens to parse. |
||
259 | * @param int $strPtr Pointer to the token where parsing starts. |
||
260 | * |
||
261 | * @return array Indexes in the same order as in the string. |
||
0 ignored issues
–
show
|
|||
262 | */ |
||
263 | private function _parseArrayIndexes ($strTokens, &$strPtr) |
||
264 | { |
||
265 | $indexes = array($this->_parseArrayIndex($strTokens, $strPtr)); |
||
266 | try { |
||
267 | while (1) { |
||
268 | $startStrPtr = $strPtr; |
||
269 | $indexes [] = $this->_parseArrayIndex($strTokens, $strPtr); |
||
270 | } |
||
271 | } catch (Exception $err) { |
||
272 | if (0 !== ($strPtr - $startStrPtr)) { |
||
273 | throw $err; |
||
274 | } |
||
275 | return $indexes; |
||
276 | } |
||
277 | }//end _parseArrayIndexes() |
||
278 | |||
279 | |||
280 | /** |
||
281 | * Grammar rule to parse the use of array index. |
||
282 | * |
||
283 | * _parseArrayIndex ::= [<index>] |
||
284 | * |
||
285 | * @exception Exception raised if $strTokens starting from $strPtr |
||
286 | * doesn't matched the rule. |
||
287 | * |
||
288 | * @param array $strTokens Tokens to parse. |
||
289 | * @param int $strPtr Pointer to the token where parsing starts. |
||
290 | * |
||
291 | * @return string Index between the 2 square brackets |
||
292 | */ |
||
293 | private function _parseArrayIndex ($strTokens, &$strPtr) |
||
294 | { |
||
295 | if ('[' !== $strTokens[$strPtr]) { |
||
296 | throw new Exception ('Expected [.'); |
||
297 | } |
||
298 | $strPtr++; |
||
299 | if (! in_array($strTokens[$strPtr][0], array(T_CONSTANT_ENCAPSED_STRING, T_LNUMBER))) { |
||
300 | throw new Exception ('Expected an array index.'); |
||
301 | } |
||
302 | $index = $strTokens[$strPtr][1]; |
||
303 | $strPtr++; |
||
304 | if (']' !== $strTokens[$strPtr]) { |
||
305 | throw new Exception ('Expected ].'); |
||
306 | } |
||
307 | $strPtr++; |
||
308 | return $index; |
||
309 | }//end _parseArrayIndex() |
||
310 | |||
311 | }//end class |
||
312 | |||
313 | /** |
||
314 | * CodeIgniter_Sniffs_Strings_VariableUsageSniff. |
||
315 | * |
||
316 | * Ensures that variables parsed in double-quoted strings are enclosed with |
||
317 | * braces to prevent greedy token parsing. |
||
318 | * Single-quoted strings don't parse variables, so there is no risk of greedy |
||
319 | * token parsing. |
||
320 | * |
||
321 | * @category PHP |
||
322 | * @package PHP_CodeSniffer |
||
323 | * @author Thomas Ernest <[email protected]> |
||
324 | * @copyright 2011 Thomas Ernest |
||
325 | * @license http://thomas.ernest.fr/developement/php_cs/licence GNU General Public License |
||
326 | * @link http://pear.php.net/package/PHP_CodeSniffer |
||
327 | */ |
||
328 | class DoubleQuoteUsageSniff extends VariableUsageSniff |
||
329 | { |
||
330 | /** |
||
331 | * Returns an array of tokens this test wants to listen for. |
||
332 | * |
||
333 | * @return array |
||
334 | */ |
||
335 | public function register() |
||
336 | { |
||
337 | return array( |
||
338 | T_DOUBLE_QUOTED_STRING, |
||
339 | T_CONSTANT_ENCAPSED_STRING, |
||
340 | ); |
||
341 | }//end register() |
||
342 | |||
343 | /** |
||
344 | * Processes this test, when one of its tokens is encountered. |
||
345 | * |
||
346 | * @param File $phpcsFile The current file being scanned. |
||
347 | * @param int $stackPtr The position of the current token |
||
348 | * in the stack passed in $tokens. |
||
349 | * |
||
350 | * @return void |
||
351 | */ |
||
352 | public function process(File $phpcsFile, $stackPtr) |
||
353 | { |
||
354 | // no variable are in the string from here |
||
355 | $tokens = $phpcsFile->getTokens(); |
||
356 | $qtString = $tokens[$stackPtr]['content']; |
||
357 | // makes sure that it is about a double quote string, |
||
358 | // since variables are not parsed out of double quoted string |
||
359 | $open_qt_str = substr($qtString, 0, 1); |
||
360 | |||
361 | // clean the enclosing quotes |
||
362 | $qtString = substr($qtString, 1, strlen($qtString) - 1 - 1); |
||
363 | |||
364 | View Code Duplication | if (0 === strcmp($open_qt_str, '"')) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
365 | $this->processDoubleQuotedString($phpcsFile, $stackPtr, $qtString); |
||
366 | } else if (0 === strcmp($open_qt_str, "'")) { |
||
367 | $this->processSingleQuotedString($phpcsFile, $stackPtr, $qtString); |
||
368 | } |
||
369 | }//end process() |
||
370 | |||
371 | |||
372 | /** |
||
373 | * Processes this test, when the token encountered is a double-quoted string. |
||
374 | * |
||
375 | * @param File $phpcsFile The current file being scanned. |
||
376 | * @param int $stackPtr The position of the current token |
||
377 | * in the stack passed in $tokens. |
||
378 | * @param string $qtString The double-quoted string content, |
||
379 | * i.e. without quotes. |
||
380 | * |
||
381 | * @return void |
||
382 | */ |
||
383 | protected function processDoubleQuotedString (File $phpcsFile, $stackPtr, $qtString) |
||
384 | { |
||
385 | // so there should be at least a single quote or a special char |
||
386 | // if there are the 2 kinds of quote and no special char, then add a warning |
||
387 | $has_variable = parent::processDoubleQuotedString($phpcsFile, $stackPtr, '"'.$qtString.'"'); |
||
388 | $has_specific_sequence = $this->_hasSpecificSequence($qtString); |
||
389 | $dbl_qt_at = strpos($qtString, '"'); |
||
390 | $smpl_qt_at = strpos($qtString, "'"); |
||
391 | if (false === $has_variable && false === $has_specific_sequence |
||
392 | && false === $smpl_qt_at |
||
393 | ) { |
||
394 | $error = 'Single-quoted strings should be used unless it contains variables, special chars like \n or single quotes.'; |
||
395 | $phpcsFile->addError($error, $stackPtr); |
||
396 | View Code Duplication | } else if (false !== $smpl_qt_at && false !== $dbl_qt_at |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
397 | && false === $has_variable && false === $has_specific_sequence |
||
398 | ) { |
||
399 | $warning = 'It is encouraged to use a single-quoted string, since it doesn\'t contain any variable nor special char though it mixes single and double quotes.'; |
||
400 | $phpcsFile->addWarning($warning, $stackPtr); |
||
401 | } |
||
402 | }//end processDoubleQuotedString() |
||
403 | |||
404 | |||
405 | /** |
||
406 | * Processes this test, when the token encountered is a single-quoted string. |
||
407 | * |
||
408 | * @param File $phpcsFile The current file being scanned. |
||
409 | * @param int $stackPtr The position of the current token |
||
410 | * in the stack passed in $tokens. |
||
411 | * @param string $qtString The single-quoted string content, |
||
412 | * i.e. without quotes. |
||
413 | * |
||
414 | * @return void |
||
415 | */ |
||
416 | protected function processSingleQuotedString (File $phpcsFile, $stackPtr, $qtString) |
||
417 | { |
||
418 | // if there is single quotes without additional double quotes, |
||
419 | // then user is allowed to use double quote to avoid having to |
||
420 | // escape single quotes. Don't add the warning, if an error was |
||
421 | // already added, because a variable was found in a single-quoted |
||
422 | // string. |
||
423 | $has_variable = parent::processSingleQuotedString($phpcsFile, $stackPtr, "'".$qtString."'"); |
||
424 | $dbl_qt_at = strpos($qtString, '"'); |
||
425 | $smpl_qt_at = strpos($qtString, "'"); |
||
426 | View Code Duplication | if (false === $has_variable && false !== $smpl_qt_at && false === $dbl_qt_at) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
427 | $warning = 'You may also use double-quoted strings if the string contains single quotes, so you do not have to use escape characters.'; |
||
428 | $phpcsFile->addWarning($warning, $stackPtr); |
||
429 | } |
||
430 | }//end processSingleQuotedString() |
||
431 | |||
432 | /** |
||
433 | * Return TRUE, if a sequence of chars that is parsed in a specific way |
||
434 | * in double-quoted strings is found, FALSE otherwise. |
||
435 | * |
||
436 | * @param string $string String in which sequence of special chars will |
||
437 | * be researched. |
||
438 | * |
||
439 | * @return TRUE, if a sequence of chars that is parsed in a specific way |
||
0 ignored issues
–
show
The doc-type
TRUE, could not be parsed: Expected "|" or "end of type", but got "," at position 4. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.
Loading history...
|
|||
440 | * in double-quoted strings is found, FALSE otherwise. |
||
441 | * |
||
442 | * @link http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.double |
||
443 | */ |
||
444 | private function _hasSpecificSequence($string) |
||
445 | { |
||
446 | $hasSpecificSequence = FALSE; |
||
447 | $specialMeaningStrs = array('\n', '\r', '\t', '\v', '\f'); |
||
448 | foreach ($specialMeaningStrs as $splStr) { |
||
449 | if (FALSE !== strpos($string, $splStr)) { |
||
450 | $hasSpecificSequence = TRUE; |
||
451 | } |
||
452 | } |
||
453 | $specialMeaningPtrns = array('\[0-7]{1,3}', '\x[0-9A-Fa-f]{1,2}'); |
||
454 | foreach ($specialMeaningPtrns as $splPtrn) { |
||
455 | if (1 === preg_match("/{$splPtrn}/", $string)) { |
||
456 | $hasSpecificSequence = TRUE; |
||
457 | } |
||
458 | } |
||
459 | return $hasSpecificSequence; |
||
460 | }//end _hasSpecificSequence() |
||
461 | |||
462 | }//end class |
||
463 | |||
464 | ?> |
||
465 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.