Skip to content

Commit ee00916

Browse files
committed
✨ switch phan for phpstan (see chillerlan/php-qrcode#277)
1 parent 8ce1775 commit ee00916

15 files changed

+122
-99
lines changed

.gitattributes

+18-15
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
/.build export-ignore
2-
/.github export-ignore
3-
/.phan export-ignore
4-
/.phpdoc export-ignore
5-
/docs export-ignore
6-
/examples export-ignore
7-
/tests export-ignore
8-
/.editorconfig export-ignore
9-
/.gitattributes export-ignore
10-
/.gitignore export-ignore
11-
/.readthedocs.yml export-ignore
12-
/phpcs.xml.dist export-ignore
13-
/phpdoc.xml.dist export-ignore
14-
/phpmd.xml.dist export-ignore
15-
/phpunit.xml.dist export-ignore
1+
/.build export-ignore
2+
/.github export-ignore
3+
/.idea export-ignore
4+
/.phan export-ignore
5+
/.phpdoc export-ignore
6+
/docs export-ignore
7+
/examples export-ignore
8+
/tests export-ignore
9+
/.editorconfig export-ignore
10+
/.gitattributes export-ignore
11+
/.gitignore export-ignore
12+
/.readthedocs.yml export-ignore
13+
/phpcs.xml.dist export-ignore
14+
/phpdoc.xml.dist export-ignore
15+
/phpmd.xml.dist export-ignore
16+
/phpunit.xml.dist export-ignore
17+
/phpstan.dist.neon export-ignore
18+
/phpstan-baseline.neon export-ignore
1619

1720
*.php diff=php

.github/workflows/ci.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ jobs:
4141
uses: shivammathur/setup-php@v2
4242
with:
4343
php-version: ${{ matrix.php-version }}
44-
extensions: ast, ${{ env.PHP_EXTENSIONS }}
44+
extensions: ${{ env.PHP_EXTENSIONS }}
4545
ini-values: ${{ env.PHP_INI_VALUES }}
4646
coverage: none
4747

@@ -51,8 +51,8 @@ jobs:
5151
- name: "Install dependencies with composer"
5252
uses: ramsey/composer-install@v3
5353

54-
- name: "Run phan"
55-
run: php vendor/bin/phan --target-php-version=${{ matrix.php-version }}
54+
- name: "Run PHPStan"
55+
run: php vendor/bin/phpstan
5656

5757

5858
tests:

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ phpcs.xml
66
phpdoc.xml
77
phpmd.xml
88
phpunit.xml
9+
phpstan.neon
910
*.phpunit.result.cache

.phan/config.php

-57
This file was deleted.

composer.json

+6-5
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,18 @@
3232
"prefer-stable": true,
3333
"require": {
3434
"php": "^8.2",
35-
"chillerlan/php-settings-container": "^3.2",
35+
"chillerlan/php-settings-container": "^3.2.1",
3636
"paragonie/constant_time_encoding": "^3.0"
3737
},
3838
"require-dev": {
3939
"ext-curl": "*",
4040
"ext-json": "*",
4141
"ext-sodium": "*",
42-
"phan/phan": "^5.4",
4342
"phpmd/phpmd": "^2.15",
43+
"phpstan/phpstan": "^1.11",
44+
"phpstan/phpstan-deprecation-rules": "^1.2",
4445
"phpunit/phpunit": "^11.2",
45-
"squizlabs/php_codesniffer": "^3.9"
46+
"squizlabs/php_codesniffer": "^3.10"
4647
},
4748
"suggest": {
4849
"chillerlan/php-qrcode": "Create QR Codes for use with an authenticator app."
@@ -58,9 +59,9 @@
5859
}
5960
},
6061
"scripts": {
61-
"phan": "@php vendor/bin/phan --allow-polyfill-parser",
6262
"phpcs": "@php vendor/bin/phpcs",
63-
"phpunit": "@php vendor/bin/phpunit"
63+
"phpunit": "@php vendor/bin/phpunit",
64+
"phpstan": "@php vendor/bin/phpstan"
6465
},
6566
"config": {
6667
"lock": false,

phpstan-baseline.neon

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
parameters:
2+
ignoreErrors:
3+
-
4+
message: "#^Cannot access offset 'server_time' on mixed\\.$#"
5+
count: 1
6+
path: src/Authenticators/SteamGuard.php
7+
8+
-
9+
message: "#^Cannot cast mixed to int\\.$#"
10+
count: 1
11+
path: src/Authenticators/SteamGuard.php
12+
13+
- # $response is always string here because CURLOPT_RETURNTRANSFER is set to true
14+
message: "#^Parameter \\#1 \\$json of function json_decode expects string, string\\|true given\\.$#"
15+
count: 1
16+
path: src/Authenticators/SteamGuard.php
17+
18+
- # the value given to getHMAC() is always int - this is most likely a false positive
19+
message: "#^Parameter \\#1 \\$counter of method chillerlan\\\\Authenticator\\\\Authenticators\\\\HOTP\\:\\:getHMAC\\(\\) expects int, float\\|int given\\.$#"
20+
count: 1
21+
path: src/Authenticators/TOTP.php
22+
23+
- # 32-bit system check
24+
message: "#^Call to function is_int\\(\\) with 59\\|1111111109\\|1111111111\\|1234567890\\|2000000000\\|20000000000 will always evaluate to true\\.$#"
25+
count: 1
26+
path: tests/Authenticators/SteamGuardTest.php
27+
28+
- # 32-bit system check
29+
message: "#^Call to function is_int\\(\\) with 59\\|1111111109\\|1111111111\\|1234567890\\|2000000000\\|20000000000 will always evaluate to true\\.$#"
30+
count: 1
31+
path: tests/Authenticators/TOTPTest.php

phpstan.dist.neon

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# https://phpstan.org/config-reference
2+
3+
parameters:
4+
level: 9
5+
tmpDir: .build/phpstan-cache
6+
paths:
7+
- examples
8+
- src
9+
- tests
10+
11+
treatPhpDocTypesAsCertain: false
12+
13+
includes:
14+
- phpstan-baseline.neon
15+
- vendor/phpstan/phpstan/conf/bleedingEdge.neon
16+
- vendor/phpstan/phpstan-deprecation-rules/rules.neon
17+
- vendor/chillerlan/php-settings-container/rules-magic-access.neon

phpunit.xml.dist

+7-11
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,24 @@
22
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
33
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
44
bootstrap="vendor/autoload.php"
5-
cacheResultFile=".build/phpunit.result.cache"
5+
cacheDirectory=".build/phpunit-cache"
66
colors="true"
77
beStrictAboutOutputDuringTests="true"
88
>
99
<testsuites>
1010
<testsuite name="php-authenticator test suite">
11-
<directory suffix=".php">./tests/</directory>
12-
<exclude>tests/Authenticators/AuthenticatorInterfaceTestAbstract.php</exclude>
11+
<directory>tests</directory>
1312
</testsuite>
1413
</testsuites>
14+
<source>
15+
<include>
16+
<directory>src</directory>
17+
</include>
18+
</source>
1519
<coverage>
1620
<report>
1721
<clover outputFile=".build/coverage/clover.xml"/>
1822
<xml outputDirectory=".build/coverage/coverage-xml"/>
1923
</report>
2024
</coverage>
21-
<logging>
22-
<junit outputFile=".build/logs/junit.xml"/>
23-
</logging>
24-
<source>
25-
<include>
26-
<directory>./src</directory>
27-
</include>
28-
</source>
2925
</phpunit>

src/AuthenticatorOptionsTrait.php

+11
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@
1717
use function strtolower;
1818
use function strtoupper;
1919

20+
/**
21+
* @property int $digits
22+
* @property int $period
23+
* @property int $secret_length
24+
* @property string $algorithm
25+
* @property string $mode
26+
* @property int $adjacent
27+
* @property int $time_offset
28+
* @property bool $useLocalTime
29+
* @property bool $forceTimeRefresh
30+
*/
2031
trait AuthenticatorOptionsTrait{
2132

2233
/**

src/Authenticators/HOTP.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,12 @@ public function getHMAC(int $counter):string{
5555
*/
5656
public function getCode(#[SensitiveParameter] string $hmac):int{
5757
$data = unpack('C*', $hmac);
58-
$b = ($data[strlen($hmac)] & 0xF);
58+
59+
if($data === false){
60+
throw new RuntimeException('error while unpacking HMAC'); // @codeCoverageIgnore
61+
}
62+
63+
$b = ($data[strlen($hmac)] & 0xF);
5964
// phpcs:ignore
6065
return (($data[$b + 1] & 0x7F) << 24) | ($data[$b + 2] << 16) | ($data[$b + 3] << 8) | $data[$b + 4];
6166
}

src/Authenticators/SteamGuard.php

+8-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use function curl_setopt_array;
2424
use function floor;
2525
use function intdiv;
26+
use function is_array;
2627
use function json_decode;
2728
use function sprintf;
2829
use function time;
@@ -129,21 +130,26 @@ public function getServerTime():int{
129130

130131
$ch = curl_init($this::steamTimeURL);
131132

133+
// it's almost impossible to run into this, but hey, phpstan happy
134+
if($ch === false){
135+
throw new RuntimeException('curl_init error'); // @codeCoverageIgnore
136+
}
137+
132138
curl_setopt_array($ch, $options);
133139

134140
$response = curl_exec($ch);
135141
$info = curl_getinfo($ch);
136142

137143
curl_close($ch);
138144

139-
if($info['http_code'] !== 200){
145+
if($info['http_code'] !== 200 || $response === false){
140146
// I'm not going to investigate the error further as this shouldn't happen usually
141147
throw new RuntimeException(sprintf('Steam API request error: HTTP/%s', $info['http_code'])); // @codeCoverageIgnore
142148
}
143149

144150
$json = json_decode($response, true);
145151

146-
if(empty($json) || !isset($json['response']['server_time'])){
152+
if(!is_array($json) || !isset($json['response']['server_time'])){
147153
throw new RuntimeException('Unable to decode Steam API response'); // @codeCoverageIgnore
148154
}
149155

tests/AuthenticatorTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public function testGetUri():void{
8484
);
8585
}
8686

87-
public function testGetUriEmptyLabelException(){
87+
public function testGetUriEmptyLabelException():void{
8888
$this->expectException(InvalidArgumentException::class);
8989
$this->expectExceptionMessage('$label and $issuer cannot be empty');
9090

tests/Common/Base32Test.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818

1919
class Base32Test extends TestCase{
2020

21+
/**
22+
* @phpstan-return array<int, array<int, string>>
23+
*/
2124
public static function base32DataProvider():array{
2225
return [
2326
['a' , 'ME' ],
@@ -37,12 +40,12 @@ public function testEncode(string $str, string $base32):void{
3740
}
3841

3942
#[DataProvider('base32DataProvider')]
40-
public function testDecode(string $str, string $base32){
43+
public function testDecode(string $str, string $base32):void{
4144
$this::assertSame($str, Base32::decode($base32));
4245
}
4346

4447
#[DataProvider('base32DataProvider')]
45-
public function testCheckCharset(string $str, string $base32){
48+
public function testCheckCharset(string $str, string $base32):void{
4649
$this->expectNotToPerformAssertions();
4750

4851
Base32::checkCharacterSet($base32);

tests/Common/Base64Test.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
*/
2424
class Base64Test extends TestCase{
2525

26+
/**
27+
* @phpstan-return array<int, array<int, string>>
28+
*/
2629
public static function base64DataProvider():array{
2730
return [
2831
['a' , 'YQ==' ],
@@ -45,7 +48,7 @@ public function testEncode(string $str, string $base64):void{
4548
}
4649

4750
#[DataProvider('base64DataProvider')]
48-
public function testDecode(string $str, string $base64){
51+
public function testDecode(string $str, string $base64):void{
4952
$decoded = Base64::decode($base64);
5053

5154
$this::assertSame($str, $decoded);
@@ -54,7 +57,7 @@ public function testDecode(string $str, string $base64){
5457
}
5558

5659
#[DataProvider('base64DataProvider')]
57-
public function testCheckCharset(string $str, string $base64){
60+
public function testCheckCharset(string $str, string $base64):void{
5861
$this->expectNotToPerformAssertions();
5962

6063
Base64::checkCharacterSet($base64);

tests/Common/HexTest.php

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
*/
2424
class HexTest extends TestCase{
2525

26+
/**
27+
* @phpstan-return array<int, array<int, string>>
28+
*/
2629
public static function hexDataProvider():array{
2730
return [
2831
['a' , '61' ],

0 commit comments

Comments
 (0)