Skip to content

Commit

Permalink
Merge pull request #479 from PHPCSStandards/develop
Browse files Browse the repository at this point in the history
Release 1.0.6
  • Loading branch information
jrfnl committed May 27, 2023
2 parents 0cfef51 + 864d5c2 commit ba259ea
Show file tree
Hide file tree
Showing 30 changed files with 485 additions and 183 deletions.
22 changes: 22 additions & 0 deletions .github/SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Security Policy

## Supported Versions

The latest patch version of the `1.x` release series is supported for security updates.

## Reporting a Vulnerability

PHPCSUtils is a developer tool and should generally not be used in a production (web accessible) environment.

Having said that, responsible disclosure of security issues is highly appreciated.

**Please do not report or discuss security vulnerabilities through public GitHub issues, discussions, or pull requests.**

Issues can be reported privately to the maintainers by opening a [Security vulnerability report](https://github.com/PHPCSStandards/PHPCSUtils/security/advisories/new).

### Preferences

* Please provide detailed reports with reproducible steps and a clearly defined impact.
* Include the version number of the vulnerable package in your report.
* Fixes are most welcome.
A private PR can be created from the security report to work on and discuss the patch.
2 changes: 1 addition & 1 deletion .github/workflows/basics.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ jobs:
remark-preset-lint-markdown-style-guide
remark-lint-checkbox-content-indent
remark-lint-linebreak-style
remark-lint-no-dead-urls
remark-lint-no-duplicate-defined-urls
remark-lint-no-empty-url
remark-lint-no-heading-like-paragraph
Expand All @@ -154,7 +155,6 @@ jobs:
remark-lint-list-item-punctuation
remark-lint-match-punctuation
remark-lint-no-hr-after-heading
remark-lint-are-links-valid-alive
remark-lint-are-links-valid-duplicate
remark-validate-links
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ jobs:
- name: Upload coverage results to Coveralls
if: ${{ success() }}
env:
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }}
COVERALLS_PARALLEL: true
COVERALLS_FLAG_NAME: php-${{ matrix.php }}-phpcs-${{ matrix.phpcs_version }}
run: php-coveralls -v -x build/logs/clover.xml
Expand All @@ -362,5 +362,5 @@ jobs:
- name: Coveralls Finished
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
github-token: ${{ secrets.COVERALLS_TOKEN }}
parallel-finished: true
2 changes: 1 addition & 1 deletion .remarkrc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
["remark-lint-linebreak-style", "unix"],
["remark-lint-link-title-style", "\""],
["remark-lint-ordered-list-marker-style", "."],
"remark-lint-no-dead-urls",
"remark-lint-no-duplicate-defined-urls",
"remark-lint-no-duplicate-definitions",
"remark-lint-no-empty-url",
Expand All @@ -29,7 +30,6 @@
"remark-lint-list-item-punctuation",
"remark-lint-match-punctuation",
"remark-lint-no-hr-after-heading",
"remark-lint-are-links-valid-alive",
"remark-lint-are-links-valid-duplicate",
"remark-validate-links"
]
Expand Down
40 changes: 40 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,45 @@ This projects adheres to [Keep a CHANGELOG](https://keepachangelog.com/) and use

_Nothing yet._


## [1.0.6] - 2023-05-27

### Changed

#### PHPCS BackCompat

* `BCFile::getClassProperties()`: sync with PHPCS 3.8.0 - support for PHP 8.2 `readonly` classes. [#470]
* `BCFile::getMethodParameters()`: sync with PHPCS 3.8.0 - support for constructor property promotion with `readonly` properties without explicit visibility. [#472]

#### Utils

* The results of the following methods will now (also) be cached for improved performance when multiple sniffs call these functions for the same token during a PHPCS run. [#464], [#466]
- `FunctionDeclarations::getProperties()`
- `Variables::getMemberProperties()`
* Additionally, the results of the `UseStatements::splitImportUseStatement()` method will be cached more often and the cache checked earlier. [#467]
* The return value of the `ControlStructures::getCaughtExceptions()` method will no longer contain "empty" entries for catch statements without a named exception. It will return an empty array instead. [#474]

#### Other

* Various small housekeeping and maintenance updates.

### Fixed

### Abstract Sniffs

* `AbstractArrayDeclarationSniff`: fixed a potential "Trying to access array offset on value of type bool" PHP notice. [#476]
* `AbstractArrayDeclarationSniff`: the abstract will no longer trigger potentially available magic `__get()`/`__set()` etc methods. [#477]

[#464]: https://github.com/PHPCSStandards/PHPCSUtils/pull/464
[#466]: https://github.com/PHPCSStandards/PHPCSUtils/pull/466
[#467]: https://github.com/PHPCSStandards/PHPCSUtils/pull/467
[#470]: https://github.com/PHPCSStandards/PHPCSUtils/pull/470
[#472]: https://github.com/PHPCSStandards/PHPCSUtils/pull/472
[#474]: https://github.com/PHPCSStandards/PHPCSUtils/pull/474
[#476]: https://github.com/PHPCSStandards/PHPCSUtils/pull/476
[#477]: https://github.com/PHPCSStandards/PHPCSUtils/pull/477


## [1.0.5] - 2023-04-17

### Fixed
Expand Down Expand Up @@ -850,6 +889,7 @@ This initial alpha release contains the following utility classes:


[Unreleased]: https://github.com/PHPCSStandards/PHPCSUtils/compare/stable...HEAD
[1.0.6]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.5...1.0.6
[1.0.5]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.4...1.0.5
[1.0.4]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.3...1.0.4
[1.0.3]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.2...1.0.3
Expand Down
10 changes: 8 additions & 2 deletions PHPCSUtils/AbstractSniffs/AbstractArrayDeclarationSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,14 @@ final public function process(File $phpcsFile, $stackPtr)
return;
}

$openClose = Arrays::getOpenClose($phpcsFile, $stackPtr, true);
if ($openClose === false) {
// Parse error or live coding.
return;
}

$this->stackPtr = $stackPtr;
$this->tokens = $phpcsFile->getTokens();
$openClose = Arrays::getOpenClose($phpcsFile, $stackPtr, true);
$this->arrayOpener = $openClose['opener'];
$this->arrayCloser = $openClose['closer'];
$this->itemCount = \count($this->arrayItems);
Expand All @@ -199,7 +204,8 @@ final public function process(File $phpcsFile, $stackPtr)
$this->processArray($phpcsFile);

// Reset select properties between calls to this sniff to lower memory usage.
unset($this->tokens, $this->arrayItems);
$this->tokens = [];
$this->arrayItems = [];
}

/**
Expand Down
82 changes: 67 additions & 15 deletions PHPCSUtils/BackCompat/BCFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,23 +138,25 @@ public static function getDeclarationName(File $phpcsFile, $stackPtr)
*
* Parameters declared using PHP 8 constructor property promotion, have these additional array indexes:
* ```php
* 'property_visibility' => string, // The property visibility as declared.
* 'visibility_token' => integer, // The stack pointer to the visibility modifier token.
* 'property_readonly' => bool, // TRUE if the readonly keyword was found.
* 'readonly_token' => integer, // The stack pointer to the readonly modifier token.
* // This index will only be set if the property is readonly.
* 'property_visibility' => string, // The property visibility as declared.
* 'visibility_token' => integer,|false // The stack pointer to the visibility modifier token.
* // or FALSE if the visibility is not explicitly declared.
* 'property_readonly' => bool, // TRUE if the readonly keyword was found.
* 'readonly_token' => integer, // The stack pointer to the readonly modifier token.
* // This index will only be set if the property is readonly.
* ```
*
* PHPCS cross-version compatible version of the `File::getMethodParameters()` method.
*
* Changelog for the PHPCS native function:
* - Introduced in PHPCS 0.0.5.
* - The upstream method has received no significant updates since PHPCS 3.7.1.
* - PHPCS 3.8.0: Added support for constructor property promotion with readonly without explicit visibility.
*
* @see \PHP_CodeSniffer\Files\File::getMethodParameters() Original source.
* @see \PHPCSUtils\Utils\FunctionDeclarations::getParameters() PHPCSUtils native improved version.
*
* @since 1.0.0
* @since 1.0.6 Sync with PHPCS 3.8.0, support for readonly properties without explicit visibility. PHPCS#3801.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
* @param int $stackPtr The position in the stack of the function token
Expand Down Expand Up @@ -380,15 +382,20 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr)
$vars[$paramCount]['type_hint_end_token'] = $typeHintEndToken;
$vars[$paramCount]['nullable_type'] = $nullableType;

if ($visibilityToken !== null) {
$vars[$paramCount]['property_visibility'] = $tokens[$visibilityToken]['content'];
$vars[$paramCount]['visibility_token'] = $visibilityToken;
if ($visibilityToken !== null || $readonlyToken !== null) {
$vars[$paramCount]['property_visibility'] = 'public';
$vars[$paramCount]['visibility_token'] = false;
$vars[$paramCount]['property_readonly'] = false;
}

if ($readonlyToken !== null) {
$vars[$paramCount]['property_readonly'] = true;
$vars[$paramCount]['readonly_token'] = $readonlyToken;
if ($visibilityToken !== null) {
$vars[$paramCount]['property_visibility'] = $tokens[$visibilityToken]['content'];
$vars[$paramCount]['visibility_token'] = $visibilityToken;
}

if ($readonlyToken !== null) {
$vars[$paramCount]['property_readonly'] = true;
$vars[$paramCount]['readonly_token'] = $readonlyToken;
}
}

if ($tokens[$i]['code'] === T_COMMA) {
Expand Down Expand Up @@ -527,19 +534,21 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr)
* array(
* 'is_abstract' => boolean, // TRUE if the abstract keyword was found.
* 'is_final' => boolean, // TRUE if the final keyword was found.
* 'is_readonly' => false, // TRUE if the readonly keyword was found.
* );
* ```
*
* PHPCS cross-version compatible version of the `File::getClassProperties()` method.
*
* Changelog for the PHPCS native function:
* - Introduced in PHPCS 1.3.0.
* - The upstream method has received no significant updates since PHPCS 3.7.1.
* - PHPCS 3.8.0: Added support for PHP 8.2 `readonly` classes.
*
* @see \PHP_CodeSniffer\Files\File::getClassProperties() Original source.
* @see \PHPCSUtils\Utils\ObjectDeclarations::getClassProperties() PHPCSUtils native improved version.
*
* @since 1.0.0
* @since 1.0.6 Sync with PHPCS 3.8.0, support for readonly classes. PHPCS#3686.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
* @param int $stackPtr The position in the stack of the `T_CLASS`
Expand All @@ -552,7 +561,50 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr)
*/
public static function getClassProperties(File $phpcsFile, $stackPtr)
{
return $phpcsFile->getClassProperties($stackPtr);
$tokens = $phpcsFile->getTokens();

if ($tokens[$stackPtr]['code'] !== T_CLASS) {
throw new RuntimeException('$stackPtr must be of type T_CLASS');
}

$valid = [
T_FINAL => T_FINAL,
T_ABSTRACT => T_ABSTRACT,
T_READONLY => T_READONLY,
T_WHITESPACE => T_WHITESPACE,
T_COMMENT => T_COMMENT,
T_DOC_COMMENT => T_DOC_COMMENT,
];

$isAbstract = false;
$isFinal = false;
$isReadonly = false;

for ($i = ($stackPtr - 1); $i > 0; $i--) {
if (isset($valid[$tokens[$i]['code']]) === false) {
break;
}

switch ($tokens[$i]['code']) {
case T_ABSTRACT:
$isAbstract = true;
break;

case T_FINAL:
$isFinal = true;
break;

case T_READONLY:
$isReadonly = true;
break;
}
}

return [
'is_abstract' => $isAbstract,
'is_final' => $isFinal,
'is_readonly' => $isReadonly,
];
}

/**
Expand Down
15 changes: 9 additions & 6 deletions PHPCSUtils/Utils/ControlStructures.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ public static function isElseIf(File $phpcsFile, $stackPtr)
* 'type_end_token' => integer, // The stack pointer to the end of the type declaration.
* )
* ```
* In case of an invalid catch structure, the array may be empty.
*
* @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the specified `$stackPtr` is not of
* type `T_CATCH` or doesn't exist.
Expand Down Expand Up @@ -243,12 +244,14 @@ public static function getCaughtExceptions(File $phpcsFile, $stackPtr)
}

if (isset(Collections::namespacedNameTokens()[$tokens[$i]['code']]) === false) {
// Add the current exception to the result array.
$exceptions[] = [
'type' => $foundName,
'type_token' => $firstToken,
'type_end_token' => $lastToken,
];
// Add the current exception to the result array if one was found.
if ($foundName !== '') {
$exceptions[] = [
'type' => $foundName,
'type_token' => $firstToken,
'type_end_token' => $lastToken,
];
}

if ($tokens[$i]['code'] === \T_BITWISE_OR) {
// Multi-catch. Reset and continue.
Expand Down
11 changes: 9 additions & 2 deletions PHPCSUtils/Utils/FunctionDeclarations.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ public static function getName(File $phpcsFile, $stackPtr)
* - Defensive coding against incorrect calls to this method.
* - More efficient checking whether a function has a body.
* - Support for PHP 8.0 identifier name tokens in return types, cross-version PHP & PHPCS.
* - Support for constructor property promotion with the PHP 8.1 readonly keyword without explicit visibility.
* - Support for the PHP 8.2 `true` type.
* - The results of this function call are cached during a PHPCS run for faster response times.
*
* @see \PHP_CodeSniffer\Files\File::getMethodProperties() Original source.
* @see \PHPCSUtils\BackCompat\BCFile::getMethodProperties() Cross-version compatible version of the original.
Expand Down Expand Up @@ -193,6 +193,10 @@ public static function getProperties(File $phpcsFile, $stackPtr)
throw new RuntimeException('$stackPtr must be of type T_FUNCTION or T_CLOSURE or an arrow function');
}

if (Cache::isCached($phpcsFile, __METHOD__, $stackPtr) === true) {
return Cache::get($phpcsFile, __METHOD__, $stackPtr);
}

if ($tokens[$stackPtr]['code'] === \T_FUNCTION) {
$valid = Tokens::$methodPrefixes;
} else {
Expand Down Expand Up @@ -292,7 +296,7 @@ public static function getProperties(File $phpcsFile, $stackPtr)
$returnType = '?' . $returnType;
}

return [
$returnValue = [
'scope' => $scope,
'scope_specified' => $scopeSpecified,
'return_type' => $returnType,
Expand All @@ -304,6 +308,9 @@ public static function getProperties(File $phpcsFile, $stackPtr)
'is_static' => $isStatic,
'has_body' => $hasBody,
];

Cache::set($phpcsFile, __METHOD__, $stackPtr, $returnValue);
return $returnValue;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion PHPCSUtils/Utils/Namespaces.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ public static function getDeclaredName(File $phpcsFile, $stackPtr, $clean = true
}

/**
* Determine the namespace an arbitrary token lives in.
* Find the stack pointer to the namespace declaration applicable for an arbitrary token.
*
* Take note:
* 1. When a namespace declaration token or a token which is part of the namespace
Expand Down
1 change: 0 additions & 1 deletion PHPCSUtils/Utils/ObjectDeclarations.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ public static function getName(File $phpcsFile, $stackPtr)
* - Handling of PHPCS annotations.
* - Handling of unorthodox docblock placement.
* - Defensive coding against incorrect calls to this method.
* - Support for PHP 8.2 readonly classes.
* - Additional `'abstract_token'`, `'final_token'`, and `'readonly_token'` indexes in the return array.
*
* @see \PHP_CodeSniffer\Files\File::getClassProperties() Original source.
Expand Down
9 changes: 5 additions & 4 deletions PHPCSUtils/Utils/UseStatements.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ public static function splitImportUseStatement(File $phpcsFile, $stackPtr)
throw new RuntimeException('$stackPtr must be an import use statement');
}

if (Cache::isCached($phpcsFile, __METHOD__, $stackPtr) === true) {
return Cache::get($phpcsFile, __METHOD__, $stackPtr);
}

$statements = [
'name' => [],
'function' => [],
Expand All @@ -208,13 +212,10 @@ public static function splitImportUseStatement(File $phpcsFile, $stackPtr)
$endOfStatement = $phpcsFile->findNext([\T_SEMICOLON, \T_CLOSE_TAG], ($stackPtr + 1));
if ($endOfStatement === false) {
// Live coding or parse error.
Cache::set($phpcsFile, __METHOD__, $stackPtr, $statements);
return $statements;
}

if (Cache::isCached($phpcsFile, __METHOD__, $stackPtr) === true) {
return Cache::get($phpcsFile, __METHOD__, $stackPtr);
}

++$endOfStatement;

$start = true;
Expand Down

0 comments on commit ba259ea

Please sign in to comment.