Skip to content

Commit eb6a95a

Browse files
authored
Fix false-positive with preg_match(): Strict comparison using === between '' and non-falsy-string…ween '' and non-falsy-string
1 parent 70448ad commit eb6a95a

File tree

2 files changed

+29
-8
lines changed

2 files changed

+29
-8
lines changed

src/Type/Regex/RegexGroupParser.php

+9-7
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ private function walkGroupAst(
367367
if (
368368
$ast->getId() === '#concatenation'
369369
&& count($children) > 0
370+
&& !$walkResult->isInOptionalQuantification()
370371
) {
371372
$meaningfulTokens = 0;
372373
foreach ($children as $child) {
@@ -400,13 +401,14 @@ private function walkGroupAst(
400401
if ($min === 0) {
401402
$walkResult = $walkResult->inOptionalQuantification(true);
402403
}
403-
if ($min >= 1) {
404-
$walkResult = $walkResult
405-
->nonEmpty(TrinaryLogic::createYes())
406-
->inOptionalQuantification(false);
407-
}
408-
if ($min >= 2 && !$inAlternation) {
409-
$walkResult = $walkResult->nonFalsy(TrinaryLogic::createYes());
404+
405+
if (!$walkResult->isInOptionalQuantification()) {
406+
if ($min >= 1) {
407+
$walkResult = $walkResult->nonEmpty(TrinaryLogic::createYes());
408+
}
409+
if ($min >= 2 && !$inAlternation) {
410+
$walkResult = $walkResult->nonFalsy(TrinaryLogic::createYes());
411+
}
410412
}
411413

412414
$walkResult = $walkResult->onlyLiterals(null);

tests/PHPStan/Analyser/nsrt/preg_match_shapes.php

+20-1
Original file line numberDiff line numberDiff line change
@@ -894,8 +894,27 @@ function testEscapedDelimiter (string $string): void {
894894
}
895895
}
896896

897-
function bugUnescapedDashAfterRange (string $string): void {
897+
function bugUnescapedDashAfterRange (string $string): void
898+
{
898899
if (preg_match('/([0-1-y])/', $string, $matches)) {
899900
assertType("array{string, non-empty-string}", $matches);
900901
}
901902
}
903+
904+
function bug11744(string $string): void
905+
{
906+
if (!preg_match('~^((/[a-z]+)?)~', $string, $matches)) {
907+
return;
908+
}
909+
assertType('array{0: string, 1: string, 2?: non-falsy-string}', $matches);
910+
911+
if (!preg_match('~^((/[a-z]+)?.*)~', $string, $matches)) {
912+
return;
913+
}
914+
assertType('array{0: string, 1: string, 2?: non-falsy-string}', $matches);
915+
916+
if (!preg_match('~^((/[a-z]+)?.+)~', $string, $matches)) {
917+
return;
918+
}
919+
assertType('array{0: string, 1: non-empty-string, 2?: non-falsy-string}', $matches);
920+
}

0 commit comments

Comments
 (0)