Repository: humbug/php-scoper (php)

Issue:
Restrict possible delimiters for regexes
In PHP in practice any character can be used for regexes. In the context of PHP-Scoper, i.e. matching symbols fully qualified names against regexes, various delimiters are causing issues. For example `\` which makes `\Foo\A` a perfectly valid case or `Bar\BW` for which `B` works out.

For this reason I think it's simpler to restrict regexes to special characters (i.e. non unicode letters) and exclude `\` as well.

Pull request description:
Restrict regex delimiters allowed
Fixes #597

Patch:
diff --git a/src/RegexChecker.php b/src/RegexChecker.php
index 8524b78..856cba4 100644
--- a/src/RegexChecker.php
+++ b/src/RegexChecker.php
@@ -43,8 +43,7 @@ final class RegexChecker
 
         $firstCharacter = $value[0];
 
-        if ('\\' === $firstCharacter) {
-            // This is not ideal as not true.
+        if (!self::isValidDelimiter($firstCharacter)) {
             return false;
         }
 
@@ -76,6 +75,13 @@ final class RegexChecker
         );
     }
 
+    private static function isValidDelimiter(string $delimiter): bool
+    {
+        // This is not ideal as not true but is good enough for our case.
+        // See https://github.com/humbug/php-scoper/issues/597
+        return '\\' !== $delimiter && native_preg_match('/^\p{L}$/u', $delimiter) === 0;
+    }
+
     private static function isValidRegexFlags(string $value): bool
     {
         if ('' === $value) {


Test patch:
diff --git a/tests/RegexCheckerTest.php b/tests/RegexCheckerTest.php
index b61f4b6..9e9ca0e 100644
--- a/tests/RegexCheckerTest.php
+++ b/tests/RegexCheckerTest.php
@@ -69,11 +69,18 @@ final class RegexCheckerTest extends TestCase
             false,
         ];
 
+        // See https://github.com/humbug/php-scoper/issues/597
         yield 'fake regex (1)' => [
             '\Foo\A',
             false,
         ];
 
+        // See https://github.com/humbug/php-scoper/issues/597
+        yield 'fake regex (2)' => [
+            'Bar\WB',
+            false,
+        ];
+
         yield 'minimal fake regex' => [
             '////',
             false,
@@ -84,6 +91,16 @@ final class RegexCheckerTest extends TestCase
             true,
         ];
 
+        yield 'regular regex with flags (1)' => [
+            '~foo~iu',
+            true,
+        ];
+
+        yield 'regular regex with flags (2)' => [
+            '#foo#iu',
+            true,
+        ];
+
         yield 'regular regex with invalid flags' => [
             '/foo/NOPE',
             false,