@@ -24,24 +24,26 @@ public function __construct(private PhpVersion $phpVersion)
2424 {
2525 }
2626
27- public function getPrintfPlaceholdersCount (string $ format ): int
27+ public function getPrintfPlaceholdersCount (string $ format ): ? int
2828 {
2929 return $ this ->getPlaceholdersCount (self ::PRINTF_SPECIFIER_PATTERN , $ format );
3030 }
3131
3232 /** @phpstan-return array<int, non-empty-list<PrintfPlaceholder>> parameter index => placeholders */
33- public function getPrintfPlaceholders (string $ format ): array
33+ public function getPrintfPlaceholders (string $ format ): ? array
3434 {
3535 return $ this ->parsePlaceholders (self ::PRINTF_SPECIFIER_PATTERN , $ format );
3636 }
3737
38- public function getScanfPlaceholdersCount (string $ format ): int
38+ public function getScanfPlaceholdersCount (string $ format ): ? int
3939 {
4040 return $ this ->getPlaceholdersCount ('(?<specifier>[cdDeEfinosuxX%s]|\[[^\]]+\]) ' , $ format );
4141 }
4242
43- /** @phpstan-return array<int, non-empty-list<PrintfPlaceholder>> parameter index => placeholders */
44- private function parsePlaceholders (string $ specifiersPattern , string $ format ): array
43+ /**
44+ * @phpstan-return array<int, non-empty-list<PrintfPlaceholder>>|null parameter index => placeholders
45+ */
46+ private function parsePlaceholders (string $ specifiersPattern , string $ format ): ?array
4547 {
4648 $ addSpecifier = '' ;
4749 if ($ this ->phpVersion ->supportsHhPrintfSpecifier ()) {
@@ -50,7 +52,7 @@ private function parsePlaceholders(string $specifiersPattern, string $format): a
5052
5153 $ specifiers = sprintf ($ specifiersPattern , $ addSpecifier );
5254
53- $ pattern = '~(?<before>%*)%(?:(?<position>\d+)\$)?[-+]?(?:[ 0]|(?: \'[^%]))?(?<width>\*)?-?\d*(?:\.(?:\d+|(?<precision>\*))?)? ' . $ specifiers . '~ ' ;
55+ $ pattern = '~(?<before>%*)%(?:(?<position>\d+)\$)?[-+]?(?:[ 0]|(?: \'[^%]))?(?<width>\*)?-?\d*(?:\.(?:\d+|(?<precision>\*))?)? ' . $ specifiers . '? ~ ' ;
5456
5557 $ matches = Strings::matchAll ($ format , $ pattern , PREG_SET_ORDER );
5658
@@ -89,13 +91,19 @@ private function parsePlaceholders(string $specifiersPattern, string $format): a
8991 $ showValueSuffix = true ;
9092 }
9193
94+ $ specifier = $ placeholder ['specifier ' ] ?? '' ;
95+ if ($ specifier === '' ) {
96+ // A placeholder is invalid.
97+ return null ;
98+ }
99+ 92100 $ parsedPlaceholders [] = new PrintfPlaceholder (
93101 sprintf ('"%s" ' , $ placeholder [0 ]) . ($ showValueSuffix ? ' (value) ' : '' ),
94102 isset ($ placeholder ['position ' ]) && $ placeholder ['position ' ] !== ''
95103 ? $ placeholder ['position ' ] - 1
96104 : $ parameterIdx ++,
97105 $ placeholderNumber ,
98- $ this ->getAcceptingTypeBySpecifier ($ placeholder [ ' specifier ' ] ?? '' ),
106+ $ this ->getAcceptingTypeBySpecifier ($ specifier ),
99107 );
100108 }
101109
@@ -124,9 +132,14 @@ private function getAcceptingTypeBySpecifier(string $specifier): string
124132 return 'mixed ' ;
125133 }
126134
127- private function getPlaceholdersCount (string $ specifiersPattern , string $ format ): int
135+ private function getPlaceholdersCount (string $ specifiersPattern , string $ format ): ? int
128136 {
129- $ paramIndices = array_keys ($ this ->parsePlaceholders ($ specifiersPattern , $ format ));
137+ $ placeholdersMap = $ this ->parsePlaceholders ($ specifiersPattern , $ format );
138+ if ($ placeholdersMap === null ) {
139+ return null ;
140+ }
141+ 142+ $ paramIndices = array_keys ($ placeholdersMap );
130143
131144 return $ paramIndices === []
132145 ? 0
0 commit comments