Skip to content

Commit 5e54dbd

Browse files
staabmondrejmirtes
authored andcommitted
infer non-falsy-string in sscanf()
1 parent a917100 commit 5e54dbd

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

src/Type/Php/SscanfFunctionDynamicReturnTypeExtension.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPStan\Analyser\Scope;
77
use PHPStan\Reflection\FunctionReflection;
88
use PHPStan\Type\Accessory\AccessoryNonEmptyStringType;
9+
use PHPStan\Type\Accessory\AccessoryNonFalsyStringType;
910
use PHPStan\Type\Constant\ConstantArrayTypeBuilder;
1011
use PHPStan\Type\Constant\ConstantIntegerType;
1112
use PHPStan\Type\Constant\ConstantStringType;
@@ -54,10 +55,17 @@ public function getTypeFromFunctionCall(
5455

5556
$type = new StringType();
5657
if ($length !== '') {
57-
$type = new IntersectionType([
58-
$type,
59-
new AccessoryNonEmptyStringType(),
60-
]);
58+
if (((int) $length) > 1) {
59+
$type = new IntersectionType([
60+
$type,
61+
new AccessoryNonFalsyStringType(),
62+
]);
63+
} else {
64+
$type = new IntersectionType([
65+
$type,
66+
new AccessoryNonEmptyStringType(),
67+
]);
68+
}
6169
}
6270

6371
if (in_array($specifier, ['d', 'o', 'u', 'x'], true)) {

tests/PHPStan/Analyser/data/sscanf.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,14 @@ function fscanfFormatInference($r) {
3737
assertType('int|null', $year);
3838
}
3939

40-
function fooo() {
40+
function fooo(string $s) {
41+
// %0s returns the whole string
42+
assertType('array{non-empty-string|null}|null', sscanf( "0" , "%0s"));
4143
assertType('array{non-empty-string|null}|null', sscanf( "123456" , "%0s"));
42-
assertType('array{non-empty-string|null}|null', sscanf( "123456" , "%3s"));
44+
45+
assertType('array{non-empty-string|null}|null', sscanf( "123456" , "%1s"));
46+
assertType('array{non-falsy-string|null}|null', sscanf( "123456" , "%2s"));
47+
assertType('array{non-falsy-string|null}|null', sscanf( "123456" , "%3s"));
48+
4349
assertType('array{int|null, int|null, int|null}|null', sscanf('00ccff', '%2x%2x%2x'));
4450
}

0 commit comments

Comments
 (0)