From 19e550f4e3059405ff94f69a4cd1b8a7a47c34f1 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 6 Oct 2024 20:08:49 +0200 Subject: [PATCH 1/6] More precise md5/sha1 return type --- resources/functionMap.php | 8 ++--- ...rictComparisonOfDifferentTypesRuleTest.php | 20 +++++++++++ .../PHPStan/Rules/Comparison/data/hashing.php | 34 +++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 tests/PHPStan/Rules/Comparison/data/hashing.php diff --git a/resources/functionMap.php b/resources/functionMap.php index f8c4bf30e0..3b9a6f5963 100644 --- a/resources/functionMap.php +++ b/resources/functionMap.php @@ -6403,8 +6403,8 @@ 'mcrypt_module_open' => ['resource|false', 'cipher'=>'string', 'cipher_directory'=>'string', 'mode'=>'string', 'mode_directory'=>'string'], 'mcrypt_module_self_test' => ['bool', 'algorithm'=>'string', 'lib_dir='=>'string'], 'mcrypt_ofb' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'], -'md5' => ['non-falsy-string', 'str'=>'string', 'raw_output='=>'bool'], -'md5_file' => ['non-falsy-string|false', 'filename'=>'string', 'raw_output='=>'bool'], +'md5' => ['(non-falsy-string&numeric-string)|(non-falsy-string&lowercase-string)', 'str'=>'string', 'raw_output='=>'bool'], +'md5_file' => ['(non-falsy-string&numeric-string)|(non-falsy-string&lowercase-string)|false', 'filename'=>'string', 'raw_output='=>'bool'], 'mdecrypt_generic' => ['string', 'td'=>'resource', 'data'=>'string'], 'Memcache::add' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'], 'Memcache::addServer' => ['bool', 'host'=>'string', 'port='=>'int', 'persistent='=>'bool', 'weight='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable', 'timeoutms='=>'int'], @@ -10446,8 +10446,8 @@ 'setRightFill' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], 'setthreadtitle' => ['bool', 'title'=>'string'], 'settype' => ['bool', '&rw_var'=>'mixed', 'type'=>'string'], -'sha1' => ['non-falsy-string', 'str'=>'string', 'raw_output='=>'bool'], -'sha1_file' => ['non-falsy-string|false', 'filename'=>'string', 'raw_output='=>'bool'], +'sha1' => ['(non-falsy-string&numeric-string)|(non-falsy-string&lowercase-string)', 'str'=>'string', 'raw_output='=>'bool'], +'sha1_file' => ['(non-falsy-string&numeric-string)|(non-falsy-string&lowercase-string)|false', 'filename'=>'string', 'raw_output='=>'bool'], 'sha256' => ['string', 'str'=>'string', 'raw_output='=>'bool'], 'sha256_file' => ['string', 'filename'=>'string', 'raw_output='=>'bool'], 'shapefileObj::__construct' => ['void', 'filename'=>'string', 'type'=>'int'], diff --git a/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php b/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php index e50ab41805..a90e0da5cc 100644 --- a/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php @@ -1121,4 +1121,24 @@ public function testBug10493(): void $this->analyse([__DIR__ . '/data/bug-10493.php'], []); } + public function testHashing(): void + { + $this->checkAlwaysTrueStrictComparison = true; + $this->analyse([__DIR__ . '/data/hashing.php'], [ + [ + "Strict comparison using === between (lowercase-string&non-falsy-string)|(non-falsy-string&numeric-string) and 'ABC' will always evaluate to false.", + 9, + ], + [ + "Strict comparison using === between (lowercase-string&non-falsy-string)|(non-falsy-string&numeric-string)|false and 'ABC' will always evaluate to false.", + 12, + ], + [ + "Strict comparison using === between (lowercase-string&non-falsy-string)|(non-falsy-string&numeric-string) and 'A' will always evaluate to false.", + 31, + 'Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.', + ], + ]); + } + } diff --git a/tests/PHPStan/Rules/Comparison/data/hashing.php b/tests/PHPStan/Rules/Comparison/data/hashing.php new file mode 100644 index 0000000000..14fad8b550 --- /dev/null +++ b/tests/PHPStan/Rules/Comparison/data/hashing.php @@ -0,0 +1,34 @@ + Date: Sun, 6 Oct 2024 20:43:04 +0200 Subject: [PATCH 2/6] fix --- src/Testing/PHPStanTestCase.php | 2 +- src/Testing/TestCaseSourceLocatorFactory.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Testing/PHPStanTestCase.php b/src/Testing/PHPStanTestCase.php index 14efcc7480..4c65e34b8f 100644 --- a/src/Testing/PHPStanTestCase.php +++ b/src/Testing/PHPStanTestCase.php @@ -54,7 +54,7 @@ abstract class PHPStanTestCase extends TestCase /** @deprecated */ public static bool $useStaticReflectionProvider = true; - /** @var array */ + /** @var array */ private static array $containers = []; /** @api */ diff --git a/src/Testing/TestCaseSourceLocatorFactory.php b/src/Testing/TestCaseSourceLocatorFactory.php index a4921c9201..1bb5ccd291 100644 --- a/src/Testing/TestCaseSourceLocatorFactory.php +++ b/src/Testing/TestCaseSourceLocatorFactory.php @@ -26,7 +26,7 @@ final class TestCaseSourceLocatorFactory { - /** @var array> */ + /** @var array> */ private static array $composerSourceLocatorsCache = []; /** From 94898c5dd8abcd6ce1ad2c6c138a8b2cdaf774ca Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 6 Oct 2024 21:30:04 +0200 Subject: [PATCH 3/6] simplify --- resources/functionMap.php | 8 ++++---- src/Testing/PHPStanTestCase.php | 2 +- src/Testing/TestCaseSourceLocatorFactory.php | 2 +- .../StrictComparisonOfDifferentTypesRuleTest.php | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/resources/functionMap.php b/resources/functionMap.php index 3b9a6f5963..a41fb94ab0 100644 --- a/resources/functionMap.php +++ b/resources/functionMap.php @@ -6403,8 +6403,8 @@ 'mcrypt_module_open' => ['resource|false', 'cipher'=>'string', 'cipher_directory'=>'string', 'mode'=>'string', 'mode_directory'=>'string'], 'mcrypt_module_self_test' => ['bool', 'algorithm'=>'string', 'lib_dir='=>'string'], 'mcrypt_ofb' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'], -'md5' => ['(non-falsy-string&numeric-string)|(non-falsy-string&lowercase-string)', 'str'=>'string', 'raw_output='=>'bool'], -'md5_file' => ['(non-falsy-string&numeric-string)|(non-falsy-string&lowercase-string)|false', 'filename'=>'string', 'raw_output='=>'bool'], +'md5' => ['(non-falsy-string&lowercase-string)', 'str'=>'string', 'raw_output='=>'bool'], +'md5_file' => ['(non-falsy-string&lowercase-string)|false', 'filename'=>'string', 'raw_output='=>'bool'], 'mdecrypt_generic' => ['string', 'td'=>'resource', 'data'=>'string'], 'Memcache::add' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'], 'Memcache::addServer' => ['bool', 'host'=>'string', 'port='=>'int', 'persistent='=>'bool', 'weight='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable', 'timeoutms='=>'int'], @@ -10446,8 +10446,8 @@ 'setRightFill' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], 'setthreadtitle' => ['bool', 'title'=>'string'], 'settype' => ['bool', '&rw_var'=>'mixed', 'type'=>'string'], -'sha1' => ['(non-falsy-string&numeric-string)|(non-falsy-string&lowercase-string)', 'str'=>'string', 'raw_output='=>'bool'], -'sha1_file' => ['(non-falsy-string&numeric-string)|(non-falsy-string&lowercase-string)|false', 'filename'=>'string', 'raw_output='=>'bool'], +'sha1' => ['(non-falsy-string&lowercase-string)', 'str'=>'string', 'raw_output='=>'bool'], +'sha1_file' => ['(non-falsy-string&lowercase-string)|false', 'filename'=>'string', 'raw_output='=>'bool'], 'sha256' => ['string', 'str'=>'string', 'raw_output='=>'bool'], 'sha256_file' => ['string', 'filename'=>'string', 'raw_output='=>'bool'], 'shapefileObj::__construct' => ['void', 'filename'=>'string', 'type'=>'int'], diff --git a/src/Testing/PHPStanTestCase.php b/src/Testing/PHPStanTestCase.php index 4c65e34b8f..14efcc7480 100644 --- a/src/Testing/PHPStanTestCase.php +++ b/src/Testing/PHPStanTestCase.php @@ -54,7 +54,7 @@ abstract class PHPStanTestCase extends TestCase /** @deprecated */ public static bool $useStaticReflectionProvider = true; - /** @var array */ + /** @var array */ private static array $containers = []; /** @api */ diff --git a/src/Testing/TestCaseSourceLocatorFactory.php b/src/Testing/TestCaseSourceLocatorFactory.php index 1bb5ccd291..a4921c9201 100644 --- a/src/Testing/TestCaseSourceLocatorFactory.php +++ b/src/Testing/TestCaseSourceLocatorFactory.php @@ -26,7 +26,7 @@ final class TestCaseSourceLocatorFactory { - /** @var array> */ + /** @var array> */ private static array $composerSourceLocatorsCache = []; /** diff --git a/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php b/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php index a90e0da5cc..4721b4e78b 100644 --- a/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php @@ -1126,11 +1126,11 @@ public function testHashing(): void $this->checkAlwaysTrueStrictComparison = true; $this->analyse([__DIR__ . '/data/hashing.php'], [ [ - "Strict comparison using === between (lowercase-string&non-falsy-string)|(non-falsy-string&numeric-string) and 'ABC' will always evaluate to false.", + "Strict comparison using === between lowercase-string&non-falsy-string and 'ABC' will always evaluate to false.", 9, ], [ - "Strict comparison using === between (lowercase-string&non-falsy-string)|(non-falsy-string&numeric-string)|false and 'ABC' will always evaluate to false.", + "Strict comparison using === between (lowercase-string&non-falsy-string)|false and 'ABC' will always evaluate to false.", 12, ], [ From 4721a890c34467e205481560217ecb0da869c5e6 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Tue, 8 Oct 2024 10:53:33 +0200 Subject: [PATCH 4/6] simplify --- resources/functionMap.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/functionMap.php b/resources/functionMap.php index a41fb94ab0..44a7ae4cde 100644 --- a/resources/functionMap.php +++ b/resources/functionMap.php @@ -6403,7 +6403,6 @@ 'mcrypt_module_open' => ['resource|false', 'cipher'=>'string', 'cipher_directory'=>'string', 'mode'=>'string', 'mode_directory'=>'string'], 'mcrypt_module_self_test' => ['bool', 'algorithm'=>'string', 'lib_dir='=>'string'], 'mcrypt_ofb' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'], -'md5' => ['(non-falsy-string&lowercase-string)', 'str'=>'string', 'raw_output='=>'bool'], 'md5_file' => ['(non-falsy-string&lowercase-string)|false', 'filename'=>'string', 'raw_output='=>'bool'], 'mdecrypt_generic' => ['string', 'td'=>'resource', 'data'=>'string'], 'Memcache::add' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'], @@ -10446,7 +10445,6 @@ 'setRightFill' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], 'setthreadtitle' => ['bool', 'title'=>'string'], 'settype' => ['bool', '&rw_var'=>'mixed', 'type'=>'string'], -'sha1' => ['(non-falsy-string&lowercase-string)', 'str'=>'string', 'raw_output='=>'bool'], 'sha1_file' => ['(non-falsy-string&lowercase-string)|false', 'filename'=>'string', 'raw_output='=>'bool'], 'sha256' => ['string', 'str'=>'string', 'raw_output='=>'bool'], 'sha256_file' => ['string', 'filename'=>'string', 'raw_output='=>'bool'], From c39762b5af7a6d7e9a2f5282bb02fd45c80a7964 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Tue, 8 Oct 2024 10:54:26 +0200 Subject: [PATCH 5/6] simplify --- resources/functionMap.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/functionMap.php b/resources/functionMap.php index 44a7ae4cde..9a09516cb1 100644 --- a/resources/functionMap.php +++ b/resources/functionMap.php @@ -6404,6 +6404,7 @@ 'mcrypt_module_self_test' => ['bool', 'algorithm'=>'string', 'lib_dir='=>'string'], 'mcrypt_ofb' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'], 'md5_file' => ['(non-falsy-string&lowercase-string)|false', 'filename'=>'string', 'raw_output='=>'bool'], +'md5' => ['non-falsy-string&lowercase-string', 'str'=>'string', 'raw_output='=>'bool'], 'mdecrypt_generic' => ['string', 'td'=>'resource', 'data'=>'string'], 'Memcache::add' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'], 'Memcache::addServer' => ['bool', 'host'=>'string', 'port='=>'int', 'persistent='=>'bool', 'weight='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable', 'timeoutms='=>'int'], @@ -10446,6 +10447,7 @@ 'setthreadtitle' => ['bool', 'title'=>'string'], 'settype' => ['bool', '&rw_var'=>'mixed', 'type'=>'string'], 'sha1_file' => ['(non-falsy-string&lowercase-string)|false', 'filename'=>'string', 'raw_output='=>'bool'], +'sha1' => ['non-falsy-string&lowercase-string', 'str'=>'string', 'raw_output='=>'bool'], 'sha256' => ['string', 'str'=>'string', 'raw_output='=>'bool'], 'sha256_file' => ['string', 'filename'=>'string', 'raw_output='=>'bool'], 'shapefileObj::__construct' => ['void', 'filename'=>'string', 'type'=>'int'], From 05fead76b579779fbb0ca7c4c3a0c71c61da7cc6 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Tue, 8 Oct 2024 10:55:22 +0200 Subject: [PATCH 6/6] Update functionMap.php --- resources/functionMap.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/functionMap.php b/resources/functionMap.php index 9a09516cb1..2dcf0feb8a 100644 --- a/resources/functionMap.php +++ b/resources/functionMap.php @@ -6403,8 +6403,8 @@ 'mcrypt_module_open' => ['resource|false', 'cipher'=>'string', 'cipher_directory'=>'string', 'mode'=>'string', 'mode_directory'=>'string'], 'mcrypt_module_self_test' => ['bool', 'algorithm'=>'string', 'lib_dir='=>'string'], 'mcrypt_ofb' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'], -'md5_file' => ['(non-falsy-string&lowercase-string)|false', 'filename'=>'string', 'raw_output='=>'bool'], 'md5' => ['non-falsy-string&lowercase-string', 'str'=>'string', 'raw_output='=>'bool'], +'md5_file' => ['(non-falsy-string&lowercase-string)|false', 'filename'=>'string', 'raw_output='=>'bool'], 'mdecrypt_generic' => ['string', 'td'=>'resource', 'data'=>'string'], 'Memcache::add' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'], 'Memcache::addServer' => ['bool', 'host'=>'string', 'port='=>'int', 'persistent='=>'bool', 'weight='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable', 'timeoutms='=>'int'], @@ -10446,8 +10446,8 @@ 'setRightFill' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], 'setthreadtitle' => ['bool', 'title'=>'string'], 'settype' => ['bool', '&rw_var'=>'mixed', 'type'=>'string'], -'sha1_file' => ['(non-falsy-string&lowercase-string)|false', 'filename'=>'string', 'raw_output='=>'bool'], 'sha1' => ['non-falsy-string&lowercase-string', 'str'=>'string', 'raw_output='=>'bool'], +'sha1_file' => ['(non-falsy-string&lowercase-string)|false', 'filename'=>'string', 'raw_output='=>'bool'], 'sha256' => ['string', 'str'=>'string', 'raw_output='=>'bool'], 'sha256_file' => ['string', 'filename'=>'string', 'raw_output='=>'bool'], 'shapefileObj::__construct' => ['void', 'filename'=>'string', 'type'=>'int'],