From 6d864c90d90028555b526ee7191d9256b04ffcf4 Mon Sep 17 00:00:00 2001 From: webimpress Date: Fri, 17 May 2019 20:49:47 +0100 Subject: [PATCH] Fixes issue with invalid type in PHPDoc - fixer infinite loop Affected sniffs: - `PHP\CorrectClassNameCase` - `PHP\DisallowFqn` --- .../Sniffs/PHP/CorrectClassNameCaseSniff.php | 5 ++++ .../Sniffs/PHP/DisallowFqnSniff.php | 23 ++++++++++--------- .../PHP/CorrectClassNameCaseUnitTest.inc | 5 ++++ .../CorrectClassNameCaseUnitTest.inc.fixed | 5 ++++ test/Sniffs/PHP/DisallowFqnUnitTest.inc | 5 ++++ test/Sniffs/PHP/DisallowFqnUnitTest.inc.fixed | 5 ++++ 6 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/WebimpressCodingStandard/Sniffs/PHP/CorrectClassNameCaseSniff.php b/src/WebimpressCodingStandard/Sniffs/PHP/CorrectClassNameCaseSniff.php index 597c345e..31eef8b4 100644 --- a/src/WebimpressCodingStandard/Sniffs/PHP/CorrectClassNameCaseSniff.php +++ b/src/WebimpressCodingStandard/Sniffs/PHP/CorrectClassNameCaseSniff.php @@ -20,6 +20,7 @@ use function implode; use function in_array; use function ltrim; +use function preg_match; use function preg_match_all; use function preg_quote; use function preg_replace; @@ -313,6 +314,10 @@ private function checkTag(File $phpcsFile, int $stackPtr) : void private function getExpectedName(File $phpcsFile, string $class, int $stackPtr) : string { $suffix = strstr($class, '['); + if ($suffix && ! preg_match('/^(\[\])+$/', $suffix)) { + return $class; + } + $class = str_replace(['[', ']'], '', $class); $imports = $this->getGlobalUses($phpcsFile); diff --git a/src/WebimpressCodingStandard/Sniffs/PHP/DisallowFqnSniff.php b/src/WebimpressCodingStandard/Sniffs/PHP/DisallowFqnSniff.php index b3a00cd2..6cd35052 100644 --- a/src/WebimpressCodingStandard/Sniffs/PHP/DisallowFqnSniff.php +++ b/src/WebimpressCodingStandard/Sniffs/PHP/DisallowFqnSniff.php @@ -20,6 +20,7 @@ use function implode; use function in_array; use function ltrim; +use function preg_match; use function preg_match_all; use function preg_quote; use function preg_replace; @@ -195,11 +196,7 @@ private function processTag( $localToImport = []; $newTypesArr = []; foreach ($typesArr as $name) { - $suffix = strstr($name, '['); - $name = str_replace(['[', ']'], '', $name); - - $newTypesArr[] = $this->getExpectedName($phpcsFile, $stackPtr + 2, $namespace, $name, $localToImport) - . $suffix; + $newTypesArr[] = $this->getExpectedName($phpcsFile, $stackPtr + 2, $namespace, $name, $localToImport); } $newTypes = implode('|', $newTypesArr); @@ -244,30 +241,34 @@ private function getExpectedName( return $name; } - // Remove leading slash from the class name - $name = ltrim($name, '\\'); + $suffix = strstr($name, '['); + if ($suffix && ! preg_match('/^(\[\])+$/', $suffix)) { + return $name; + } + + $name = str_replace(['[', ']'], '', ltrim($name, '\\')); if (stripos($name . '\\', $namespace . '\\') === 0) { - return substr($name, strlen($namespace) + 1); + return substr($name, strlen($namespace) + 1) . $suffix; } $alias = $this->getAliasFromName($name); foreach ($this->imported['class'] ?? [] as $class) { // If namespace or part of it is already imported if (stripos($name . '\\', $class['fqn'] . '\\') === 0) { - return $class['name']; + return $class['name'] . $suffix; } } // We can't suggest anything in that case if (! $this->isValidClassName($phpcsFile, $stackPtr, $alias, $name)) { - return '\\' . $name; + return '\\' . $name . $suffix; } // We need to import it $toImport += $this->import('class', $name, $alias); - return $alias; + return $alias . $suffix; } private function processString( diff --git a/test/Sniffs/PHP/CorrectClassNameCaseUnitTest.inc b/test/Sniffs/PHP/CorrectClassNameCaseUnitTest.inc index a3615a83..ef712f6c 100644 --- a/test/Sniffs/PHP/CorrectClassNameCaseUnitTest.inc +++ b/test/Sniffs/PHP/CorrectClassNameCaseUnitTest.inc @@ -91,4 +91,9 @@ class MyClass public function trav(iterable $a) { } + + /** + * @param \Bar[]\Foo[] $param + */ + abstract public function invalidTypeFormatIsNotChanged($param); } diff --git a/test/Sniffs/PHP/CorrectClassNameCaseUnitTest.inc.fixed b/test/Sniffs/PHP/CorrectClassNameCaseUnitTest.inc.fixed index 6bbfa70c..2852c503 100644 --- a/test/Sniffs/PHP/CorrectClassNameCaseUnitTest.inc.fixed +++ b/test/Sniffs/PHP/CorrectClassNameCaseUnitTest.inc.fixed @@ -91,4 +91,9 @@ class MyClass public function trav(iterable $a) { } + + /** + * @param \Bar[]\Foo[] $param + */ + abstract public function invalidTypeFormatIsNotChanged($param); } diff --git a/test/Sniffs/PHP/DisallowFqnUnitTest.inc b/test/Sniffs/PHP/DisallowFqnUnitTest.inc index 393e4c96..303e4670 100644 --- a/test/Sniffs/PHP/DisallowFqnUnitTest.inc +++ b/test/Sniffs/PHP/DisallowFqnUnitTest.inc @@ -144,4 +144,9 @@ class TheClass extends \ MyNamespace \ Hello \ ParentClass implements \ArrayAcce } }; } + + /** + * @param \Bar[]\Foo[] $param + */ + abstract public function invalidTypeFormatIsNotChanged($param); } diff --git a/test/Sniffs/PHP/DisallowFqnUnitTest.inc.fixed b/test/Sniffs/PHP/DisallowFqnUnitTest.inc.fixed index 798b32b0..6966d028 100644 --- a/test/Sniffs/PHP/DisallowFqnUnitTest.inc.fixed +++ b/test/Sniffs/PHP/DisallowFqnUnitTest.inc.fixed @@ -169,4 +169,9 @@ class TheClass extends ParentClass implements ArrayAccess, Countable } }; } + + /** + * @param \Bar[]\Foo[] $param + */ + abstract public function invalidTypeFormatIsNotChanged($param); }