Skip to content

Commit 6b1c30b

Browse files
committed
PHP 8.3 | Tokenizer/PHP + Generic/UnconditionalIfStatement: bug fix
When analyzing code during live coding, a situation could occur where the open parenthesis for an `if` control structure exists, but not a closing parenthesis. In that case, `$end` would be set to `-1` (via `-- null`) and the `for` loop would never even run, but a warning would still be thrown for the code. This warning is a false positive and should be avoided. On top of that, PHP 8.3 deprecates the use of the increment/decrement operators on non-float/non-integer values, which can cause the below warning when running the sniff on PHP 8.3. ``` An error occurred during processing; checking has been aborted. The error message was: Decrement on type null has no effect, this will change in the next major version of PHP in path\to\src\Standards\Generic\Sniffs\CodeAnalysis\UnconditionalIfStatementSniff.php on line 72 ``` Both the incorrect sniff warning, as well as the PHP 8.3 deprecation warning will now be avoided via the defensive coding added to the sniff. When debugging the issue on the command line with the added test and using the following command `phpcs -ps ./generic/tests/codeanalysis/UnconditionalIfStatementUnitTest.inc --standard=Generic --sniffs=Generic.CodeAnalysis.UnconditionalIfStatement`, I was not receiving any output at all. Digging deeper, I discovered two (loosely related) bugs in the Tokenizer/PHP class, which were the cause of that and which could be seen when running the tests: ``` Undefined array key 63 path\to\src\Tokenizers\PHP.php:3074 path\to\src\Tokenizers\Tokenizer.php:103 path\to\src\Files\File.php:577 path\to\src\Files\File.php:331 path\to\src\Files\LocalFile.php:92 path\to\tests\Standards\AbstractSniffUnitTest.php:175 path\to\tests\TestSuite7.php:28 ``` This bug is fixed by fixing the incorrect comparison on line 3073. ... which then exposed the next bug: ``` Undefined array key 63 path\to\src\Tokenizers\PHP.php:3080 path\to\src\Tokenizers\Tokenizer.php:103 path\to\src\Files\File.php:577 path\to\src\Files\File.php:331 path\to\src\Files\LocalFile.php:92 path\to\tests\Standards\AbstractSniffUnitTest.php:175 path\to\tests\TestSuite7.php:28 ``` ... which is fixed by adding some extra defensive coding in the condition. All three fixes are covered by the one test which was added.
1 parent b737635 commit 6b1c30b

File tree

3 files changed

+10
-4
lines changed

3 files changed

+10
-4
lines changed

src/Standards/Generic/Sniffs/CodeAnalysis/UnconditionalIfStatementSniff.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public function process(File $phpcsFile, $stackPtr)
6464
$token = $tokens[$stackPtr];
6565

6666
// Skip if statement without body.
67-
if (isset($token['parenthesis_opener']) === false) {
67+
if (isset($token['parenthesis_opener'], $token['parenthesis_closer']) === false) {
6868
return;
6969
}
7070

src/Standards/Generic/Tests/CodeAnalysis/UnconditionalIfStatementUnitTest.inc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,8 @@ if (true) {
1010

1111
if (file_exists(__FILE__) === true) {
1212

13-
}
13+
}
14+
15+
// Intentional parse error/live coding.
16+
// This needs to be the last test in the file.
17+
if(true

src/Tokenizers/PHP.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3131,14 +3131,16 @@ protected function processAdditional()
31313131
|| $this->tokens[$i]['code'] === T_FALSE
31323132
|| $this->tokens[$i]['code'] === T_NULL
31333133
) {
3134-
for ($x = ($i + 1); $i < $numTokens; $x++) {
3134+
for ($x = ($i + 1); $x < $numTokens; $x++) {
31353135
if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false) {
31363136
// Non-whitespace content.
31373137
break;
31383138
}
31393139
}
31403140

3141-
if (isset($this->tstringContexts[$this->tokens[$x]['code']]) === true) {
3141+
if ($x !== $numTokens
3142+
&& isset($this->tstringContexts[$this->tokens[$x]['code']]) === true
3143+
) {
31423144
if (PHP_CODESNIFFER_VERBOSITY > 1) {
31433145
$line = $this->tokens[$i]['line'];
31443146
$type = $this->tokens[$i]['type'];

0 commit comments

Comments
 (0)