Skip to content
Closed
4 changes: 4 additions & 0 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,10 @@ jobs:
- script: |
cd e2e/bug-11819
../../bin/phpstan
- script: |
cd e2e/bug-12629
../../bin/phpstan --generate-baseline # should generate without crash
../../bin/phpstan # should re-analyze without new errors

steps:
- name: "Checkout"
Expand Down
19 changes: 19 additions & 0 deletions e2e/bug-12629/phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
parameters:
ignoreErrors:
-
message: '#^Method Bug12629\\Bug12629\:\:is_macintosh_enc\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: src/bug-12629.php

-
message: '#^Method Bug12629\\Bug12629\:\:is_macintosh_enc\(\) has parameter \$s with no type specified\.$#'
identifier: missingType.parameter
count: 1
path: src/bug-12629.php

-
message: '#^Method Bug12629\\Bug12629\:\:is_macintosh_enc\(\) is unused\.$#'
identifier: method.unused
count: 1
path: src/bug-12629.php
7 changes: 7 additions & 0 deletions e2e/bug-12629/phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
includes:
- phpstan-baseline.neon

parameters:
level: 8
paths:
- src
17 changes: 17 additions & 0 deletions e2e/bug-12629/src/bug-12629.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Bug12629;

class Bug12629 {
private function is_macintosh_enc($s) {

if(!is_string($s)) {
return false;
}

preg_match_all("![\x80-\x9f]!u", $s, $matchesMacintosh);
preg_match_all("!\xc3[\x80-\x9f]!u", $s, $matchesUtf8);

return count($matchesMacintosh[0]) > 0 && 0 == count($matchesUtf8[0]);
}
}
17 changes: 16 additions & 1 deletion src/Rules/Regexp/RegularExpressionPatternRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\ShouldNotHappenException;
use PHPStan\Type\Regex\RegexExpressionHelper;
use function in_array;
use function sprintf;
use function str_starts_with;
use function strlen;
use function strpos;
use function strtolower;
use function substr;

/**
* @implements Rule<Node\Expr\FuncCall>
Expand Down Expand Up @@ -123,7 +127,18 @@ private function validatePattern(string $pattern): ?string
try {
Strings::match('', $pattern);
} catch (RegexpException $e) {
return $e->getMessage();
$invalidPatternMessage = $e->getMessage();
try {
Strings::match($invalidPatternMessage, '//u');
return $invalidPatternMessage;
} catch (RegexpException) {
$patternPos = strpos($invalidPatternMessage, 'pattern:');
if ($patternPos === false) {
throw new ShouldNotHappenException();
}
// strip invalid utf-8 pattern contents to keep the error message NEON parsable.
return substr($invalidPatternMessage, 0, $patternPos + strlen('pattern:') - 1);
}
}

return null;
Expand Down
17 changes: 17 additions & 0 deletions tests/PHPStan/Rules/Regexp/RegularExpressionPatternRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -332,4 +332,21 @@ public function dataArrayShapePatterns(): iterable
];
}

public function testBug12629(): void
{
$this->analyse(
[__DIR__ . '/data/bug-12629.php'],
[
[
'Regex pattern is invalid: Compilation failed: UTF-8 error: isolated byte with 0x80 bit set at offset 1 in pattern',
12,
],
[
'Regex pattern is invalid: Compilation failed: UTF-8 error: byte 2 top bits not 0x80 at offset 0 in pattern',
13,
],
],
);
}

}
17 changes: 17 additions & 0 deletions tests/PHPStan/Rules/Regexp/data/bug-12629.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Bug12629b;

class Bug12629 {
private function is_macintosh_enc($s) {

if(!is_string($s)) {
return false;
}

preg_match_all("![\x80-\x9f]!u", $s, $matchesMacintosh);
preg_match_all("!\xc3[\x80-\x9f]!u", $s, $matchesUtf8);

return count($matchesMacintosh[0]) > 0 && 0 == count($matchesUtf8[0]);
}
}
Loading