Skip to content

Commit

Permalink
Merge pull request #816 from PHPCSStandards/feature/file-getdeclarati…
Browse files Browse the repository at this point in the history
…onname-hardening-against-parse-errors

File::getDeclarationName(): prevent incorrect result during live coding
  • Loading branch information
jrfnl authored Feb 15, 2025
2 parents e53a925 + 604b7a0 commit f117c2b
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 9 deletions.
11 changes: 10 additions & 1 deletion src/Files/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -1304,8 +1304,17 @@ public function getDeclarationName($stackPtr)
return $this->tokens[$stackPtr]['content'];
}

$stopPoint = $this->numTokens;
if (isset($this->tokens[$stackPtr]['parenthesis_opener']) === true) {
// For functions, stop searching at the parenthesis opener.
$stopPoint = $this->tokens[$stackPtr]['parenthesis_opener'];
} else if (isset($this->tokens[$stackPtr]['scope_opener']) === true) {
// For OO tokens, stop searching at the open curly.
$stopPoint = $this->tokens[$stackPtr]['scope_opener'];
}

$content = null;
for ($i = $stackPtr; $i < $this->numTokens; $i++) {
for ($i = $stackPtr; $i < $stopPoint; $i++) {
if ($this->tokens[$i]['code'] === T_STRING) {
$content = $this->tokens[$i]['content'];
break;
Expand Down
5 changes: 5 additions & 0 deletions tests/Core/File/GetDeclarationNameParseError1Test.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

/* testLiveCoding */
// Intentional parse error. This must be the only test in the file.
function // Comment.
37 changes: 37 additions & 0 deletions tests/Core/File/GetDeclarationNameParseError1Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
/**
* Tests for the \PHP_CodeSniffer\Files\File::getDeclarationName method.
*
* @author Juliette Reinders Folmer <phpcs_nospam@adviesenzo.nl>
* @copyright 2025 PHPCSStandards Contributors
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/

namespace PHP_CodeSniffer\Tests\Core\File;

use PHP_CodeSniffer\Tests\Core\AbstractMethodUnitTest;

/**
* Tests for the \PHP_CodeSniffer\Files\File:getDeclarationName method.
*
* @covers \PHP_CodeSniffer\Files\File::getDeclarationName
*/
final class GetDeclarationNameParseError1Test extends AbstractMethodUnitTest
{


/**
* Test receiving "null" in case of a parse error.
*
* @return void
*/
public function testGetDeclarationNameNull()
{
$target = $this->getTargetToken('/* testLiveCoding */', T_FUNCTION);
$result = self::$phpcsFile->getDeclarationName($target);
$this->assertNull($result);

}//end testGetDeclarationNameNull()


}//end class
6 changes: 6 additions & 0 deletions tests/Core/File/GetDeclarationNameParseError2Test.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php

/* testLiveCoding */
// Intentional parse error/live coding. This must be the only test in the file.
// Safeguarding that the utility method does not confuse the `string` type with a function name.
$closure = function (string $param) use ($var
37 changes: 37 additions & 0 deletions tests/Core/File/GetDeclarationNameParseError2Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
/**
* Tests for the \PHP_CodeSniffer\Files\File::getDeclarationName method.
*
* @author Juliette Reinders Folmer <phpcs_nospam@adviesenzo.nl>
* @copyright 2025 PHPCSStandards Contributors
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/

namespace PHP_CodeSniffer\Tests\Core\File;

use PHP_CodeSniffer\Tests\Core\AbstractMethodUnitTest;

/**
* Tests for the \PHP_CodeSniffer\Files\File:getDeclarationName method.
*
* @covers \PHP_CodeSniffer\Files\File::getDeclarationName
*/
final class GetDeclarationNameParseError2Test extends AbstractMethodUnitTest
{


/**
* Test receiving "null" in case of a parse error.
*
* @return void
*/
public function testGetDeclarationNameNull()
{
$target = $this->getTargetToken('/* testLiveCoding */', T_FUNCTION);
$result = self::$phpcsFile->getDeclarationName($target);
$this->assertNull($result);

}//end testGetDeclarationNameNull()


}//end class
4 changes: 0 additions & 4 deletions tests/Core/File/GetDeclarationNameTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,3 @@ function &self() {}

/* testFunctionReturnByRefWithReservedKeywordStatic */
function &static() {}

/* testLiveCoding */
// Intentional parse error. This has to be the last test in the file.
function // Comment.
4 changes: 0 additions & 4 deletions tests/Core/File/GetDeclarationNameTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,6 @@ public static function dataGetDeclarationNameNull()
'testMarker' => '/* testAnonClassExtendsWithoutParens */',
'targetType' => T_ANON_CLASS,
],
'live-coding' => [
'testMarker' => '/* testLiveCoding */',
'targetType' => T_FUNCTION,
],
];

}//end dataGetDeclarationNameNull()
Expand Down

0 comments on commit f117c2b

Please sign in to comment.