Skip to content

Commit 7868ea5

Browse files
Improve hash return type
1 parent 01bf65c commit 7868ea5

File tree

3 files changed

+29
-27
lines changed

3 files changed

+29
-27
lines changed

resources/functionMap.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3909,18 +3909,18 @@
39093909
'HaruPage::stroke' => ['bool', 'close_path='=>'bool'],
39103910
'HaruPage::textOut' => ['bool', 'x'=>'float', 'y'=>'float', 'text'=>'string'],
39113911
'HaruPage::textRect' => ['bool', 'left'=>'float', 'top'=>'float', 'right'=>'float', 'bottom'=>'float', 'text'=>'string', 'align='=>'int'],
3912-
'hash' => ['non-empty-string|false', 'algo'=>'string', 'data'=>'string', 'raw_output='=>'bool'],
3912+
'hash' => ['(non-falsy-string&lowercase-string)|false', 'algo'=>'string', 'data'=>'string', 'raw_output='=>'bool'],
39133913
'hash_algos' => ['non-empty-list<non-falsy-string>'],
39143914
'hash_copy' => ['HashContext', 'context'=>'HashContext'],
39153915
'hash_equals' => ['bool', 'known_string'=>'string', 'user_string'=>'string'],
3916-
'hash_file' => ['non-empty-string|false', 'algo'=>'string', 'filename'=>'string', 'raw_output='=>'bool'],
3917-
'hash_final' => ['non-empty-string', 'context'=>'HashContext', 'raw_output='=>'bool'],
3918-
'hash_hkdf' => ['non-empty-string|false', 'algo'=>'string', 'key'=>'string', 'length='=>'int', 'info='=>'string', 'salt='=>'string'],
3919-
'hash_hmac' => ['non-empty-string|false', 'algo'=>'string', 'data'=>'string', 'key'=>'string', 'raw_output='=>'bool'],
3916+
'hash_file' => ['(non-falsy-string&lowercase-string)|false', 'algo'=>'string', 'filename'=>'string', 'raw_output='=>'bool'],
3917+
'hash_final' => ['non-falsy-string&lowercase-string', 'context'=>'HashContext', 'raw_output='=>'bool'],
3918+
'hash_hkdf' => ['(non-falsy-string&lowercase-string)|false', 'algo'=>'string', 'key'=>'string', 'length='=>'int', 'info='=>'string', 'salt='=>'string'],
3919+
'hash_hmac' => ['(non-falsy-string&lowercase-string)|false', 'algo'=>'string', 'data'=>'string', 'key'=>'string', 'raw_output='=>'bool'],
39203920
'hash_hmac_algos' => ['non-empty-list<non-falsy-string>'],
3921-
'hash_hmac_file' => ['non-empty-string|false', 'algo'=>'string', 'filename'=>'string', 'key'=>'string', 'raw_output='=>'bool'],
3921+
'hash_hmac_file' => ['(non-falsy-string&lowercase-string)|false', 'algo'=>'string', 'filename'=>'string', 'key'=>'string', 'raw_output='=>'bool'],
39223922
'hash_init' => ['HashContext', 'algo'=>'string', 'options='=>'int', 'key='=>'string'],
3923-
'hash_pbkdf2' => ['non-empty-string|false', 'algo'=>'string', 'password'=>'string', 'salt'=>'string', 'iterations'=>'int', 'length='=>'int', 'raw_output='=>'bool'],
3923+
'hash_pbkdf2' => ['(non-falsy-string&lowercase-string)|false', 'algo'=>'string', 'password'=>'string', 'salt'=>'string', 'iterations'=>'int', 'length='=>'int', 'raw_output='=>'bool'],
39243924
'hash_update' => ['bool', 'context'=>'HashContext', 'data'=>'string'],
39253925
'hash_update_file' => ['bool', 'context'=>'HashContext', 'filename'=>'string', 'scontext='=>'?HashContext'],
39263926
'hash_update_stream' => ['int', 'context'=>'HashContext', 'handle'=>'resource', 'length='=>'int'],

src/Type/Php/HashFunctionsReturnTypeExtension.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
use PHPStan\Php\PhpVersion;
88
use PHPStan\Reflection\FunctionReflection;
99
use PHPStan\Reflection\ParametersAcceptorSelector;
10-
use PHPStan\Type\Accessory\AccessoryNonEmptyStringType;
10+
use PHPStan\Type\Accessory\AccessoryLowercaseStringType;
11+
use PHPStan\Type\Accessory\AccessoryNonFalsyStringType;
1112
use PHPStan\Type\Constant\ConstantBooleanType;
1213
use PHPStan\Type\Constant\ConstantStringType;
1314
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
@@ -111,24 +112,25 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
111112

112113
$neverType = new NeverType();
113114
$falseType = new ConstantBooleanType(false);
114-
$nonEmptyString = new IntersectionType([
115+
$nonFalsyLowercaseString = new IntersectionType([
115116
new StringType(),
116-
new AccessoryNonEmptyStringType(),
117+
new AccessoryNonFalsyStringType(),
118+
new AccessoryLowercaseStringType(),
117119
]);
118120

119121
$invalidAlgorithmType = $this->phpVersion->throwsValueErrorForInternalFunctions() ? $neverType : $falseType;
120122
$functionData = self::SUPPORTED_FUNCTIONS[strtolower($functionReflection->getName())];
121123

122124
$returnTypes = array_map(
123-
function (ConstantStringType $type) use ($functionData, $nonEmptyString, $invalidAlgorithmType) {
125+
function (ConstantStringType $type) use ($functionData, $nonFalsyLowercaseString, $invalidAlgorithmType) {
124126
$algorithm = strtolower($type->getValue());
125127
if (!in_array($algorithm, $this->hashAlgorithms, true)) {
126128
return $invalidAlgorithmType;
127129
}
128130
if ($functionData['cryptographic'] && in_array($algorithm, self::NON_CRYPTOGRAPHIC_ALGORITHMS, true)) {
129131
return $invalidAlgorithmType;
130132
}
131-
return $nonEmptyString;
133+
return $nonFalsyLowercaseString;
132134
},
133135
$constantAlgorithmTypes,
134136
);

tests/PHPStan/Analyser/nsrt/hash-functions.php

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,44 +13,44 @@ class HashFunctionTests
1313

1414
public function hash_hmac(): void
1515
{
16-
assertType('non-empty-string', hash_hmac('md5', 'data', 'key'));
17-
assertType('non-empty-string', hash_hmac('sha256', 'data', 'key'));
16+
assertType('lowercase-string&non-falsy-string', hash_hmac('md5', 'data', 'key'));
17+
assertType('lowercase-string&non-falsy-string', hash_hmac('sha256', 'data', 'key'));
1818
}
1919

2020
public function hash_hmac_file(string $string): void
2121
{
22-
assertType('non-empty-string|false', hash_hmac_file('md5', 'filename', 'key'));
23-
assertType('non-empty-string|false', hash_hmac_file('sha256', 'filename', 'key'));
24-
assertType('(non-empty-string|false)', hash_hmac_file($string, 'filename', 'key'));
22+
assertType('(lowercase-string&non-falsy-string)|false', hash_hmac_file('md5', 'filename', 'key'));
23+
assertType('(lowercase-string&non-falsy-string)|false', hash_hmac_file('sha256', 'filename', 'key'));
24+
assertType('((lowercase-string&non-falsy-string)|false)', hash_hmac_file($string, 'filename', 'key'));
2525
}
2626

2727
public function hash($mixed): void
2828
{
29-
assertType('non-empty-string', hash('sha256', 'data', false));
30-
assertType('non-empty-string', hash('sha256', 'data', true));
31-
assertType('non-empty-string', hash('md5', $mixed, false));
29+
assertType('lowercase-string&non-falsy-string', hash('sha256', 'data', false));
30+
assertType('lowercase-string&non-falsy-string', hash('sha256', 'data', true));
31+
assertType('lowercase-string&non-falsy-string', hash('md5', $mixed, false));
3232
}
3333

3434
public function hash_file(): void
3535
{
36-
assertType('non-empty-string|false', hash_file('sha256', 'filename', false));
37-
assertType('non-empty-string|false', hash_file('sha256', 'filename', true));
38-
assertType('non-empty-string|false', hash_file('crc32', 'filename'));
36+
assertType('(lowercase-string&non-falsy-string)|false', hash_file('sha256', 'filename', false));
37+
assertType('(lowercase-string&non-falsy-string|false', hash_file('sha256', 'filename', true));
38+
assertType('(lowercase-string&non-falsy-string|false', hash_file('crc32', 'filename'));
3939
}
4040

4141
public function hash_hkdf(): void
4242
{
43-
assertType('non-empty-string', hash_hkdf('sha256', 'key'));
43+
assertType('lowercase-string&non-falsy-string', hash_hkdf('sha256', 'key'));
4444
}
4545

4646
public function hash_pbkdf2(): void
4747
{
48-
assertType('non-empty-string', hash_pbkdf2('sha256', 'password', 'salt', 1000));
48+
assertType('lowercase-string&non-falsy-string', hash_pbkdf2('sha256', 'password', 'salt', 1000));
4949
}
5050

5151
public function caseSensitive()
5252
{
53-
assertType('non-empty-string', hash('SHA256', 'data'));
53+
assertType('lowercase-string&non-falsy-string', hash('SHA256', 'data'));
5454
}
5555

5656
public function constantStrings(int $type)
@@ -69,7 +69,7 @@ public function constantStrings(int $type)
6969
return;
7070
}
7171

72-
assertType('non-empty-string', hash_pbkdf2($algorithm, 'password', 'salt', 1000));
72+
assertType('lowercase-string&non-falsy-string', hash_pbkdf2($algorithm, 'password', 'salt', 1000));
7373
}
7474

7575
}

0 commit comments

Comments
 (0)