From e432e11d36cb86bf0c64f6027ac334042d684368 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 22 Feb 2025 11:56:12 +0100 Subject: [PATCH 01/14] Reproduce bug 12629 --- .github/workflows/e2e-tests.yml | 3 +++ e2e/bug-12629/phpstan-baseline.neon | 31 +++++++++++++++++++++++++++++ e2e/bug-12629/phpstan.neon | 7 +++++++ e2e/bug-12629/src/bug-12629.php | 17 ++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 e2e/bug-12629/phpstan-baseline.neon create mode 100644 e2e/bug-12629/phpstan.neon create mode 100644 e2e/bug-12629/src/bug-12629.php diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 4b90be1ec3..8f2417bbb6 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -322,6 +322,9 @@ jobs: - script: | cd e2e/bug-11819 ../../bin/phpstan + - script: | + cd e2e/bug-12629 + ../../bin/phpstan steps: - name: "Checkout" diff --git a/e2e/bug-12629/phpstan-baseline.neon b/e2e/bug-12629/phpstan-baseline.neon new file mode 100644 index 0000000000..0f45e631d7 --- /dev/null +++ b/e2e/bug-12629/phpstan-baseline.neon @@ -0,0 +1,31 @@ +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 + + - + message: '#^Regex pattern is invalid\: Compilation failed\: UTF\-8 error\: byte 2 top bits not 0x80 at offset 0 in pattern\: \!Ã\[€\-Ÿ\]\!u$#' + identifier: regexp.pattern + count: 1 + path: src/bug-12629.php + + - + message: '#^Regex pattern is invalid\: Compilation failed\: UTF\-8 error\: isolated byte with 0x80 bit set at offset 1 in pattern\: \!\[€\-Ÿ\]\!u$#' + identifier: regexp.pattern + count: 1 + path: src/bug-12629.php diff --git a/e2e/bug-12629/phpstan.neon b/e2e/bug-12629/phpstan.neon new file mode 100644 index 0000000000..ddbf4c2114 --- /dev/null +++ b/e2e/bug-12629/phpstan.neon @@ -0,0 +1,7 @@ +includes: + - phpstan-baseline.neon + +parameters: + level: 8 + paths: + - src diff --git a/e2e/bug-12629/src/bug-12629.php b/e2e/bug-12629/src/bug-12629.php new file mode 100644 index 0000000000..701a78520a --- /dev/null +++ b/e2e/bug-12629/src/bug-12629.php @@ -0,0 +1,17 @@ + 0 && 0 == count($matchesUtf8[0]); + } +} From cee0cd7bce8b76765c99c555c3efd6fb60fb704f Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 22 Feb 2025 12:15:16 +0100 Subject: [PATCH 02/14] strip invalid utf-8 pattern contents to keep the error message NEON parsable. --- e2e/bug-12629/phpstan-baseline.neon | 4 ++-- src/Rules/Regexp/RegularExpressionPatternRule.php | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/e2e/bug-12629/phpstan-baseline.neon b/e2e/bug-12629/phpstan-baseline.neon index 0f45e631d7..7357ce738a 100644 --- a/e2e/bug-12629/phpstan-baseline.neon +++ b/e2e/bug-12629/phpstan-baseline.neon @@ -19,13 +19,13 @@ parameters: path: src/bug-12629.php - - message: '#^Regex pattern is invalid\: Compilation failed\: UTF\-8 error\: byte 2 top bits not 0x80 at offset 0 in pattern\: \!Ã\[€\-Ÿ\]\!u$#' + message: '#^Regex pattern is invalid\: Compilation failed\: UTF\-8 error\: byte 2 top bits not 0x80 at offset 0 in pattern$#' identifier: regexp.pattern count: 1 path: src/bug-12629.php - - message: '#^Regex pattern is invalid\: Compilation failed\: UTF\-8 error\: isolated byte with 0x80 bit set at offset 1 in pattern\: \!\[€\-Ÿ\]\!u$#' + message: '#^Regex pattern is invalid\: Compilation failed\: UTF\-8 error\: isolated byte with 0x80 bit set at offset 1 in pattern$#' identifier: regexp.pattern count: 1 path: src/bug-12629.php diff --git a/src/Rules/Regexp/RegularExpressionPatternRule.php b/src/Rules/Regexp/RegularExpressionPatternRule.php index e15bdeb13b..ea233d9687 100644 --- a/src/Rules/Regexp/RegularExpressionPatternRule.php +++ b/src/Rules/Regexp/RegularExpressionPatternRule.php @@ -123,6 +123,10 @@ private function validatePattern(string $pattern): ?string try { Strings::match('', $pattern); } catch (RegexpException $e) { + if (str_contains($e->getMessage(), 'UTF-8 error')) { + // strip invalid utf-8 pattern contents to keep the error message NEON parsable. + return substr($e->getMessage(), 0, strrpos($e->getMessage(), ':')); + } return $e->getMessage(); } From 9f388bf4a24f98bfb45854bad943fe1403b3208b Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 22 Feb 2025 12:19:47 +0100 Subject: [PATCH 03/14] fix --- src/Rules/Regexp/RegularExpressionPatternRule.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Rules/Regexp/RegularExpressionPatternRule.php b/src/Rules/Regexp/RegularExpressionPatternRule.php index ea233d9687..cc66a11a1a 100644 --- a/src/Rules/Regexp/RegularExpressionPatternRule.php +++ b/src/Rules/Regexp/RegularExpressionPatternRule.php @@ -12,8 +12,11 @@ use PHPStan\Type\Regex\RegexExpressionHelper; use function in_array; use function sprintf; +use function str_contains; use function str_starts_with; +use function strrpos; use function strtolower; +use function substr; /** * @implements Rule @@ -123,9 +126,10 @@ private function validatePattern(string $pattern): ?string try { Strings::match('', $pattern); } catch (RegexpException $e) { - if (str_contains($e->getMessage(), 'UTF-8 error')) { + $lastColonPos = strrpos($e->getMessage(), ':'); + if (str_contains($e->getMessage(), 'UTF-8 error') && $lastColonPos !== false) { // strip invalid utf-8 pattern contents to keep the error message NEON parsable. - return substr($e->getMessage(), 0, strrpos($e->getMessage(), ':')); + return substr($e->getMessage(), 0, $lastColonPos); } return $e->getMessage(); } From 3a1186302b2be28d8ee7a16781495761aff9b410 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 22 Feb 2025 12:20:58 +0100 Subject: [PATCH 04/14] Update RegularExpressionPatternRule.php --- src/Rules/Regexp/RegularExpressionPatternRule.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Rules/Regexp/RegularExpressionPatternRule.php b/src/Rules/Regexp/RegularExpressionPatternRule.php index cc66a11a1a..a4069234fd 100644 --- a/src/Rules/Regexp/RegularExpressionPatternRule.php +++ b/src/Rules/Regexp/RegularExpressionPatternRule.php @@ -9,6 +9,7 @@ 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; @@ -126,8 +127,11 @@ private function validatePattern(string $pattern): ?string try { Strings::match('', $pattern); } catch (RegexpException $e) { - $lastColonPos = strrpos($e->getMessage(), ':'); - if (str_contains($e->getMessage(), 'UTF-8 error') && $lastColonPos !== false) { + if (str_contains($e->getMessage(), 'UTF-8 error')) { + $lastColonPos = strrpos($e->getMessage(), ':'); + if ($lastColonPos === false) { + throw new ShouldNotHappenException(); + } // strip invalid utf-8 pattern contents to keep the error message NEON parsable. return substr($e->getMessage(), 0, $lastColonPos); } From 182d35bb0e3a3d76f2c7ae173d592927f8ae10a8 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 22 Feb 2025 14:30:24 +0100 Subject: [PATCH 05/14] fix --- .github/workflows/e2e-tests.yml | 3 ++- e2e/bug-12629/phpstan-baseline.neon | 12 ------------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 8f2417bbb6..65af9e9639 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -324,7 +324,8 @@ jobs: ../../bin/phpstan - script: | cd e2e/bug-12629 - ../../bin/phpstan + ../../bin/phpstan --generate-baseline # should generate without crash + ../../bin/phpstan # should re-analyze without new errors steps: - name: "Checkout" diff --git a/e2e/bug-12629/phpstan-baseline.neon b/e2e/bug-12629/phpstan-baseline.neon index 7357ce738a..9b03d7b91d 100644 --- a/e2e/bug-12629/phpstan-baseline.neon +++ b/e2e/bug-12629/phpstan-baseline.neon @@ -17,15 +17,3 @@ parameters: identifier: method.unused count: 1 path: src/bug-12629.php - - - - message: '#^Regex pattern is invalid\: Compilation failed\: UTF\-8 error\: byte 2 top bits not 0x80 at offset 0 in pattern$#' - identifier: regexp.pattern - count: 1 - path: src/bug-12629.php - - - - message: '#^Regex pattern is invalid\: Compilation failed\: UTF\-8 error\: isolated byte with 0x80 bit set at offset 1 in pattern$#' - identifier: regexp.pattern - count: 1 - path: src/bug-12629.php From 748e64dfaaeeeb507d7c048aecf45a0e332f146b Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 22 Feb 2025 14:35:22 +0100 Subject: [PATCH 06/14] simplify --- src/Rules/Regexp/RegularExpressionPatternRule.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Rules/Regexp/RegularExpressionPatternRule.php b/src/Rules/Regexp/RegularExpressionPatternRule.php index a4069234fd..2a655b5739 100644 --- a/src/Rules/Regexp/RegularExpressionPatternRule.php +++ b/src/Rules/Regexp/RegularExpressionPatternRule.php @@ -128,12 +128,12 @@ private function validatePattern(string $pattern): ?string Strings::match('', $pattern); } catch (RegexpException $e) { if (str_contains($e->getMessage(), 'UTF-8 error')) { - $lastColonPos = strrpos($e->getMessage(), ':'); - if ($lastColonPos === false) { + $patternPos = strpos($e->getMessage(), 'pattern:'); + if ($patternPos === false) { throw new ShouldNotHappenException(); } // strip invalid utf-8 pattern contents to keep the error message NEON parsable. - return substr($e->getMessage(), 0, $lastColonPos); + return substr($e->getMessage(), 0, $patternPos); } return $e->getMessage(); } From bb41d830963b8e48c91b82f790e232a62dbd35a7 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 22 Feb 2025 14:43:04 +0100 Subject: [PATCH 07/14] assert baseline after test --- .github/workflows/e2e-tests.yml | 4 ++++ e2e/bug-12629/phpstan-baseline.neon.expect | 26 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 e2e/bug-12629/phpstan-baseline.neon.expect diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 65af9e9639..f1437d5f69 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -326,6 +326,7 @@ jobs: cd e2e/bug-12629 ../../bin/phpstan --generate-baseline # should generate without crash ../../bin/phpstan # should re-analyze without new errors + ../bashunit -a assert_files_equals phpstan-baseline.neon phpstan-baseline.neon.expect steps: - name: "Checkout" @@ -342,5 +343,8 @@ jobs: - name: "Install dependencies" run: "composer install --no-interaction --no-progress" + - name: "Install bashunit" + run: "curl -s https://bashunit.typeddevs.com/install.sh | bash -s e2e/ 0.17.0" + - name: "Test" run: ${{ matrix.script }} diff --git a/e2e/bug-12629/phpstan-baseline.neon.expect b/e2e/bug-12629/phpstan-baseline.neon.expect new file mode 100644 index 0000000000..a4652a8568 --- /dev/null +++ b/e2e/bug-12629/phpstan-baseline.neon.expect @@ -0,0 +1,26 @@ +parameters: + ignoreErrors: + - + message: "#^Method Bug12629\\\\Bug12629\\:\\:is_macintosh_enc\\(\\) has no return type specified\\.$#" + count: 1 + path: src/bug-12629.php + + - + message: "#^Method Bug12629\\\\Bug12629\\:\\:is_macintosh_enc\\(\\) has parameter \\$s with no type specified\\.$#" + count: 1 + path: src/bug-12629.php + + - + message: "#^Method Bug12629\\\\Bug12629\\:\\:is_macintosh_enc\\(\\) is unused\\.$#" + count: 1 + path: src/bug-12629.php + + - + message: "#^Regex pattern is invalid\\: Compilation failed\\: UTF\\-8 error\\: byte 2 top bits not 0x80 at offset 0 in pattern$#" + count: 1 + path: src/bug-12629.php + + - + message: "#^Regex pattern is invalid\\: Compilation failed\\: UTF\\-8 error\\: isolated byte with 0x80 bit set at offset 1 in pattern$#" + count: 1 + path: src/bug-12629.php From 5cd62c8b79f944f47aad29dbdb1745ab5a3c9bff Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 22 Feb 2025 14:43:31 +0100 Subject: [PATCH 08/14] cs --- src/Rules/Regexp/RegularExpressionPatternRule.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Rules/Regexp/RegularExpressionPatternRule.php b/src/Rules/Regexp/RegularExpressionPatternRule.php index 2a655b5739..961b3075ab 100644 --- a/src/Rules/Regexp/RegularExpressionPatternRule.php +++ b/src/Rules/Regexp/RegularExpressionPatternRule.php @@ -15,7 +15,7 @@ use function sprintf; use function str_contains; use function str_starts_with; -use function strrpos; +use function strpos; use function strtolower; use function substr; From 022d052c1fabb0fc8be08cbda0b3b30f8dc08652 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 22 Feb 2025 14:48:41 +0100 Subject: [PATCH 09/14] Update RegularExpressionPatternRule.php --- src/Rules/Regexp/RegularExpressionPatternRule.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Rules/Regexp/RegularExpressionPatternRule.php b/src/Rules/Regexp/RegularExpressionPatternRule.php index 961b3075ab..13582e114e 100644 --- a/src/Rules/Regexp/RegularExpressionPatternRule.php +++ b/src/Rules/Regexp/RegularExpressionPatternRule.php @@ -133,7 +133,7 @@ private function validatePattern(string $pattern): ?string throw new ShouldNotHappenException(); } // strip invalid utf-8 pattern contents to keep the error message NEON parsable. - return substr($e->getMessage(), 0, $patternPos); + return substr($e->getMessage(), 0, $patternPos + strlen('pattern:') - 1); } return $e->getMessage(); } From 4a64c9396a6bf720015d48ba3a687790121a8526 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 22 Feb 2025 14:49:05 +0100 Subject: [PATCH 10/14] Update RegularExpressionPatternRule.php --- src/Rules/Regexp/RegularExpressionPatternRule.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Rules/Regexp/RegularExpressionPatternRule.php b/src/Rules/Regexp/RegularExpressionPatternRule.php index 13582e114e..6603dbe093 100644 --- a/src/Rules/Regexp/RegularExpressionPatternRule.php +++ b/src/Rules/Regexp/RegularExpressionPatternRule.php @@ -15,6 +15,7 @@ use function sprintf; use function str_contains; use function str_starts_with; +use function strlen; use function strpos; use function strtolower; use function substr; From dd036c14b4f984b389cb956f420edfd46628f4b6 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 22 Feb 2025 14:55:57 +0100 Subject: [PATCH 11/14] use simpler unit test --- .github/workflows/e2e-tests.yml | 4 --- e2e/bug-12629/phpstan-baseline.neon.expect | 26 ------------------- .../RegularExpressionPatternRuleTest.php | 17 ++++++++++++ tests/PHPStan/Rules/Regexp/data/bug-12629.php | 17 ++++++++++++ 4 files changed, 34 insertions(+), 30 deletions(-) delete mode 100644 e2e/bug-12629/phpstan-baseline.neon.expect create mode 100644 tests/PHPStan/Rules/Regexp/data/bug-12629.php diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index f1437d5f69..65af9e9639 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -326,7 +326,6 @@ jobs: cd e2e/bug-12629 ../../bin/phpstan --generate-baseline # should generate without crash ../../bin/phpstan # should re-analyze without new errors - ../bashunit -a assert_files_equals phpstan-baseline.neon phpstan-baseline.neon.expect steps: - name: "Checkout" @@ -343,8 +342,5 @@ jobs: - name: "Install dependencies" run: "composer install --no-interaction --no-progress" - - name: "Install bashunit" - run: "curl -s https://bashunit.typeddevs.com/install.sh | bash -s e2e/ 0.17.0" - - name: "Test" run: ${{ matrix.script }} diff --git a/e2e/bug-12629/phpstan-baseline.neon.expect b/e2e/bug-12629/phpstan-baseline.neon.expect deleted file mode 100644 index a4652a8568..0000000000 --- a/e2e/bug-12629/phpstan-baseline.neon.expect +++ /dev/null @@ -1,26 +0,0 @@ -parameters: - ignoreErrors: - - - message: "#^Method Bug12629\\\\Bug12629\\:\\:is_macintosh_enc\\(\\) has no return type specified\\.$#" - count: 1 - path: src/bug-12629.php - - - - message: "#^Method Bug12629\\\\Bug12629\\:\\:is_macintosh_enc\\(\\) has parameter \\$s with no type specified\\.$#" - count: 1 - path: src/bug-12629.php - - - - message: "#^Method Bug12629\\\\Bug12629\\:\\:is_macintosh_enc\\(\\) is unused\\.$#" - count: 1 - path: src/bug-12629.php - - - - message: "#^Regex pattern is invalid\\: Compilation failed\\: UTF\\-8 error\\: byte 2 top bits not 0x80 at offset 0 in pattern$#" - count: 1 - path: src/bug-12629.php - - - - message: "#^Regex pattern is invalid\\: Compilation failed\\: UTF\\-8 error\\: isolated byte with 0x80 bit set at offset 1 in pattern$#" - count: 1 - path: src/bug-12629.php diff --git a/tests/PHPStan/Rules/Regexp/RegularExpressionPatternRuleTest.php b/tests/PHPStan/Rules/Regexp/RegularExpressionPatternRuleTest.php index b376382f18..370c007dca 100644 --- a/tests/PHPStan/Rules/Regexp/RegularExpressionPatternRuleTest.php +++ b/tests/PHPStan/Rules/Regexp/RegularExpressionPatternRuleTest.php @@ -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, + ], + ], + ); + } + } diff --git a/tests/PHPStan/Rules/Regexp/data/bug-12629.php b/tests/PHPStan/Rules/Regexp/data/bug-12629.php new file mode 100644 index 0000000000..bf72b60e19 --- /dev/null +++ b/tests/PHPStan/Rules/Regexp/data/bug-12629.php @@ -0,0 +1,17 @@ + 0 && 0 == count($matchesUtf8[0]); + } +} From b474c7ac0721acd867bc7ff5506f1f408f635c01 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 22 Feb 2025 15:07:14 +0100 Subject: [PATCH 12/14] fix php 7.2 --- src/Rules/Regexp/RegularExpressionPatternRule.php | 7 +++++-- .../Rules/Regexp/RegularExpressionPatternRuleTest.php | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Rules/Regexp/RegularExpressionPatternRule.php b/src/Rules/Regexp/RegularExpressionPatternRule.php index 6603dbe093..04a5685f98 100644 --- a/src/Rules/Regexp/RegularExpressionPatternRule.php +++ b/src/Rules/Regexp/RegularExpressionPatternRule.php @@ -13,8 +13,8 @@ use PHPStan\Type\Regex\RegexExpressionHelper; use function in_array; use function sprintf; -use function str_contains; use function str_starts_with; +use function stripos; use function strlen; use function strpos; use function strtolower; @@ -128,7 +128,10 @@ private function validatePattern(string $pattern): ?string try { Strings::match('', $pattern); } catch (RegexpException $e) { - if (str_contains($e->getMessage(), 'UTF-8 error')) { + if ( + stripos($e->getMessage(), 'Compilation failed') !== false + && stripos($e->getMessage(), 'UTF-8') !== false + ) { $patternPos = strpos($e->getMessage(), 'pattern:'); if ($patternPos === false) { throw new ShouldNotHappenException(); diff --git a/tests/PHPStan/Rules/Regexp/RegularExpressionPatternRuleTest.php b/tests/PHPStan/Rules/Regexp/RegularExpressionPatternRuleTest.php index 370c007dca..b32178dfc2 100644 --- a/tests/PHPStan/Rules/Regexp/RegularExpressionPatternRuleTest.php +++ b/tests/PHPStan/Rules/Regexp/RegularExpressionPatternRuleTest.php @@ -334,6 +334,10 @@ public function dataArrayShapePatterns(): iterable public function testBug12629(): void { + if (PHP_VERSION_ID < 70300) { + $this->markTestSkipped('This test requires PHP >= 7.3.0'); + } + $this->analyse( [__DIR__ . '/data/bug-12629.php'], [ From daecadcbc191f00f9dce58599a588f31df0ec350 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 23 Feb 2025 07:02:38 +0100 Subject: [PATCH 13/14] more generic fix --- src/Rules/Regexp/RegularExpressionPatternRule.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Rules/Regexp/RegularExpressionPatternRule.php b/src/Rules/Regexp/RegularExpressionPatternRule.php index 04a5685f98..4955f66d9c 100644 --- a/src/Rules/Regexp/RegularExpressionPatternRule.php +++ b/src/Rules/Regexp/RegularExpressionPatternRule.php @@ -14,7 +14,6 @@ use function in_array; use function sprintf; use function str_starts_with; -use function stripos; use function strlen; use function strpos; use function strtolower; @@ -128,18 +127,18 @@ private function validatePattern(string $pattern): ?string try { Strings::match('', $pattern); } catch (RegexpException $e) { - if ( - stripos($e->getMessage(), 'Compilation failed') !== false - && stripos($e->getMessage(), 'UTF-8') !== false - ) { - $patternPos = strpos($e->getMessage(), 'pattern:'); + $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($e->getMessage(), 0, $patternPos + strlen('pattern:') - 1); + return substr($invalidPatternMessage, 0, $patternPos + strlen('pattern:') - 1); } - return $e->getMessage(); } return null; From 0f1b09f61c2c4c5897073c4918556fe540190011 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 23 Feb 2025 07:08:26 +0100 Subject: [PATCH 14/14] generic fix should also work on php 7.2 --- .../PHPStan/Rules/Regexp/RegularExpressionPatternRuleTest.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/PHPStan/Rules/Regexp/RegularExpressionPatternRuleTest.php b/tests/PHPStan/Rules/Regexp/RegularExpressionPatternRuleTest.php index b32178dfc2..370c007dca 100644 --- a/tests/PHPStan/Rules/Regexp/RegularExpressionPatternRuleTest.php +++ b/tests/PHPStan/Rules/Regexp/RegularExpressionPatternRuleTest.php @@ -334,10 +334,6 @@ public function dataArrayShapePatterns(): iterable public function testBug12629(): void { - if (PHP_VERSION_ID < 70300) { - $this->markTestSkipped('This test requires PHP >= 7.3.0'); - } - $this->analyse( [__DIR__ . '/data/bug-12629.php'], [