Skip to content

Commit f8cd771

Browse files
committed
RegexArrayShapeMatcher - Fix matching literal "-" in character classes
1 parent 14fd384 commit f8cd771

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

src/Type/Regex/RegexGroupParser.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,11 @@ private function getLiteralValue(TreeNode $node, ?array &$onlyLiterals, bool $ap
508508
$token = $node->getValueToken();
509509
$value = $node->getValueValue();
510510

511-
if (in_array($token, ['literal', 'escaped_end_class'], true)) {
511+
if (
512+
in_array($token, ['literal', 'escaped_end_class'], true)
513+
// literal "-" in front/back of a character class like '[-a-z]' or '[abc-]', not forming a range
514+
|| $token === 'range'
515+
) {
512516
if (str_contains($patternModifiers, 'x') && trim($value) === '') {
513517
return null;
514518
}
@@ -517,7 +521,7 @@ private function getLiteralValue(TreeNode $node, ?array &$onlyLiterals, bool $ap
517521
return substr($value, 1);
518522
} elseif (
519523
$appendLiterals
520-
&& $token === 'literal'
524+
&& in_array($token, ['literal', 'range'], true)
521525
&& $onlyLiterals !== null
522526
&& !in_array($value, ['.'], true)
523527
) {
@@ -533,11 +537,6 @@ private function getLiteralValue(TreeNode $node, ?array &$onlyLiterals, bool $ap
533537
return $value;
534538
}
535539

536-
// literal "-" in front/back of a character class like '[-a-z]' or '[abc-]', not forming a range
537-
if ($token === 'range') {
538-
return $value;
539-
}
540-
541540
// literal "[" or "]" inside character classes '[[]' or '[]]'
542541
if (in_array($token, ['class_', '_class_literal'], true)) {
543542
return $value;

tests/PHPStan/Analyser/nsrt/preg_match_shapes.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,3 +699,11 @@ function (string $s): void {
699699
preg_match('~a|(\d)|(\s)~', $s, $matches);
700700
assertType("array{0?: string, 1?: '', 2?: non-empty-string}|array{0?: string, 1?: numeric-string}", $matches);
701701
};
702+
703+
function bug11490 (string $expression): void {
704+
$matches = [];
705+
706+
if (preg_match('/([-+])?([\d]+)%/', $expression, $matches) === 1) {
707+
assertType("array{string, ''|'+'|'-', numeric-string}", $matches);
708+
}
709+
}

0 commit comments

Comments
 (0)