Skip to content

Commit f117c2b

Browse files
authored
Merge pull request PHPCSStandards#816 from PHPCSStandards/feature/file-getdeclarationname-hardening-against-parse-errors
File::getDeclarationName(): prevent incorrect result during live coding
2 parents e53a925 + 604b7a0 commit f117c2b

7 files changed

+95
-9
lines changed

src/Files/File.php

+10-1
Original file line numberDiff line numberDiff line change
@@ -1304,8 +1304,17 @@ public function getDeclarationName($stackPtr)
13041304
return $this->tokens[$stackPtr]['content'];
13051305
}
13061306

1307+
$stopPoint = $this->numTokens;
1308+
if (isset($this->tokens[$stackPtr]['parenthesis_opener']) === true) {
1309+
// For functions, stop searching at the parenthesis opener.
1310+
$stopPoint = $this->tokens[$stackPtr]['parenthesis_opener'];
1311+
} else if (isset($this->tokens[$stackPtr]['scope_opener']) === true) {
1312+
// For OO tokens, stop searching at the open curly.
1313+
$stopPoint = $this->tokens[$stackPtr]['scope_opener'];
1314+
}
1315+
13071316
$content = null;
1308-
for ($i = $stackPtr; $i < $this->numTokens; $i++) {
1317+
for ($i = $stackPtr; $i < $stopPoint; $i++) {
13091318
if ($this->tokens[$i]['code'] === T_STRING) {
13101319
$content = $this->tokens[$i]['content'];
13111320
break;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
/* testLiveCoding */
4+
// Intentional parse error. This must be the only test in the file.
5+
function // Comment.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
/**
3+
* Tests for the \PHP_CodeSniffer\Files\File::getDeclarationName method.
4+
*
5+
* @author Juliette Reinders Folmer <[email protected]>
6+
* @copyright 2025 PHPCSStandards Contributors
7+
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
8+
*/
9+
10+
namespace PHP_CodeSniffer\Tests\Core\File;
11+
12+
use PHP_CodeSniffer\Tests\Core\AbstractMethodUnitTest;
13+
14+
/**
15+
* Tests for the \PHP_CodeSniffer\Files\File:getDeclarationName method.
16+
*
17+
* @covers \PHP_CodeSniffer\Files\File::getDeclarationName
18+
*/
19+
final class GetDeclarationNameParseError1Test extends AbstractMethodUnitTest
20+
{
21+
22+
23+
/**
24+
* Test receiving "null" in case of a parse error.
25+
*
26+
* @return void
27+
*/
28+
public function testGetDeclarationNameNull()
29+
{
30+
$target = $this->getTargetToken('/* testLiveCoding */', T_FUNCTION);
31+
$result = self::$phpcsFile->getDeclarationName($target);
32+
$this->assertNull($result);
33+
34+
}//end testGetDeclarationNameNull()
35+
36+
37+
}//end class
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
/* testLiveCoding */
4+
// Intentional parse error/live coding. This must be the only test in the file.
5+
// Safeguarding that the utility method does not confuse the `string` type with a function name.
6+
$closure = function (string $param) use ($var
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
/**
3+
* Tests for the \PHP_CodeSniffer\Files\File::getDeclarationName method.
4+
*
5+
* @author Juliette Reinders Folmer <[email protected]>
6+
* @copyright 2025 PHPCSStandards Contributors
7+
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
8+
*/
9+
10+
namespace PHP_CodeSniffer\Tests\Core\File;
11+
12+
use PHP_CodeSniffer\Tests\Core\AbstractMethodUnitTest;
13+
14+
/**
15+
* Tests for the \PHP_CodeSniffer\Files\File:getDeclarationName method.
16+
*
17+
* @covers \PHP_CodeSniffer\Files\File::getDeclarationName
18+
*/
19+
final class GetDeclarationNameParseError2Test extends AbstractMethodUnitTest
20+
{
21+
22+
23+
/**
24+
* Test receiving "null" in case of a parse error.
25+
*
26+
* @return void
27+
*/
28+
public function testGetDeclarationNameNull()
29+
{
30+
$target = $this->getTargetToken('/* testLiveCoding */', T_FUNCTION);
31+
$result = self::$phpcsFile->getDeclarationName($target);
32+
$this->assertNull($result);
33+
34+
}//end testGetDeclarationNameNull()
35+
36+
37+
}//end class

tests/Core/File/GetDeclarationNameTest.inc

-4
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,3 @@ function &self() {}
9696

9797
/* testFunctionReturnByRefWithReservedKeywordStatic */
9898
function &static() {}
99-
100-
/* testLiveCoding */
101-
// Intentional parse error. This has to be the last test in the file.
102-
function // Comment.

tests/Core/File/GetDeclarationNameTest.php

-4
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,6 @@ public static function dataGetDeclarationNameNull()
8484
'testMarker' => '/* testAnonClassExtendsWithoutParens */',
8585
'targetType' => T_ANON_CLASS,
8686
],
87-
'live-coding' => [
88-
'testMarker' => '/* testLiveCoding */',
89-
'targetType' => T_FUNCTION,
90-
],
9187
];
9288

9389
}//end dataGetDeclarationNameNull()

0 commit comments

Comments
 (0)