Fix counting *scanf() format string placeholders#5594
Fix counting *scanf() format string placeholders#5594hakre wants to merge 2 commits intophpstan:2.1.xfrom
*scanf() format string placeholders#5594Conversation
57da830 to
5742f2b
Compare
sscanf/fscanf format string placeholderssscanf/fscanf format string placeholders
|
This pull request has been marked as ready for review. |
sscanf/fscanf format string placeholders*scanf() format string placeholders
|
Do you know by chance why https://github.com/phpstan/phpstan-src/actions/runs/25431166468/job/74597885107 keeps failing on my changes? I'd like to better understand @staabm |
we see the same errors on others PRs targeting 2.1.x -> this means these errors are not related to your PR |
04f1759 to
bd2dc56
Compare
| use const PHP_INT_MAX; | ||
| use const PHP_VERSION_ID; | ||
|
|
||
| #[CoversMethod(PrintfHelper::class, 'getScanfPlaceholdersCount')] |
There was a problem hiding this comment.
we don't use Covers*/Uses* attributes. please remove them.
There was a problem hiding this comment.
please find the coverage attributes removed.
| return new PhpVersion($versionId); | ||
| } | ||
|
|
||
| public static function dataLegacyVersionIds(): Generator |
There was a problem hiding this comment.
what is this complicated method doing? couldn't we just have a data-provider which returns a few representative "hard-coded" data-pairs ?
There was a problem hiding this comment.
absolutely – please find it now with just a few hard‑coded IDs.
8a37d48 to
ddd449b
Compare
Additional by-catch fix of a variable misnomer in 023fa08 ("Fix printf parameters rule", 2017-04-02) spotted during review.
Update PrintfHelper.php to make
public function getScanfPlaceholdersCount(string $format): ?int`
return the sscanf() vetted number of placeholders that return/assign
conversions.
Addresses long-standing regressions reported originally in
[phpstan-10260].
References:
- [phpstan-10260]
- phpstan/phpstan#10260 (comment)
- [phpstan-src-5591]
- [phpstan-14567]
- https://3v4l.org/WR85Q
[phpstan-10260]: phpstan/phpstan#10260
[phpstan-src-5591]: phpstan#5591
[phpstan-14567]: phpstan/phpstan#14567
| #[RequiresPhp('< 8.0.0')] | ||
| public function testReturnsNullForInvalidPatternOnLegacyPhpVersion(): void | ||
| { | ||
| $this->assertNull($this->printf->getScanfPlaceholdersCount('%a')); | ||
| } | ||
|
|
||
| #[RequiresPhp('>= 8.0.0')] | ||
| public function testReturnsNullForInvalidPatternOnPhp8(): void | ||
| { | ||
| $this->assertNull($this->printf->getScanfPlaceholdersCount('%a')); | ||
| } |
There was a problem hiding this comment.
these 2 tests look identical. can't we just merge them and remove the #[RequiresPhp('>= 8.0.0')]?
| if ($this->phpVersion->throwsValueErrorForInternalFunctions()) { | ||
| try { | ||
| $result = sscanf('', '%*n' . $format); | ||
| } catch (ValueError) { | ||
| return null; | ||
| } | ||
| } else { | ||
| $result = @sscanf('', '%*n' . $format); | ||
| } | ||
| if ($result === null) { | ||
| return null; | ||
| } | ||
| return count($result); |
There was a problem hiding this comment.
I think this can be simplified
| if ($this->phpVersion->throwsValueErrorForInternalFunctions()) { | |
| try { | |
| $result = sscanf('', '%*n' . $format); | |
| } catch (ValueError) { | |
| return null; | |
| } | |
| } else { | |
| $result = @sscanf('', '%*n' . $format); | |
| } | |
| if ($result === null) { | |
| return null; | |
| } | |
| return count($result); | |
| try { | |
| $result = sscanf('', '%*n' . $format); | |
| } catch (ValueError) { | |
| return null; | |
| } | |
| if ($result === null) { | |
| return null; | |
| } | |
| return count($result); |
which would also simplify the tests IMO
Update PrintfHelper.php:
Make
public function getScanfPlaceholdersCount(string $format): ?intreturning the sscanf() vetted number of placeholders that give/return/assign conversions.refs:
sscanf/fscanfformat string at NUL byte before counting placeholders #5591