diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index a4dcf16408..ec20027659 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -220,12 +220,24 @@ jobs: echo "$OUTPUT" ../bashunit -a contains 'Invalid entry in ignoreErrors' "$OUTPUT" ../bashunit -a contains 'tests is neither a directory, nor a file path, nor a fnmatch pattern.' "$OUTPUT" + - script: | + cd e2e/bad-exclude-paths + OUTPUT=$(../../bin/phpstan analyse -c phpneon.php || true) + echo "$OUTPUT" + ../bashunit -a contains 'Invalid entry in ignoreErrors' "$OUTPUT" + ../bashunit -a contains 'src/test.php is neither a directory, nor a file path, nor a fnmatch pattern.' "$OUTPUT" - script: | cd e2e/bad-exclude-paths OUTPUT=$(../../bin/phpstan analyse -c excludePaths.neon || true) echo "$OUTPUT" ../bashunit -a contains 'Invalid entry in excludePaths' "$OUTPUT" ../bashunit -a contains 'tests is neither a directory, nor a file path, nor a fnmatch pattern.' "$OUTPUT" + - script: | + cd e2e/bad-exclude-paths + OUTPUT=$(../../bin/phpstan analyse -c phpneon2.php || true) + echo "$OUTPUT" + ../bashunit -a contains 'Invalid entry in excludePaths' "$OUTPUT" + ../bashunit -a contains 'src/test.php is neither a directory, nor a file path, nor a fnmatch pattern.' "$OUTPUT" steps: - name: "Checkout" diff --git a/e2e/bad-exclude-paths/phpneon.php b/e2e/bad-exclude-paths/phpneon.php new file mode 100644 index 0000000000..92ebd989a1 --- /dev/null +++ b/e2e/bad-exclude-paths/phpneon.php @@ -0,0 +1,17 @@ + [ + __DIR__ . '/../../conf/bleedingEdge.neon', + ], + 'parameters' => [ + 'level' => '8', + 'paths' => [__DIR__ . '/src'], + 'ignoreErrors' => [ + [ + 'message' => '#aaa#', + 'path' => 'src/test.php', // not absolute path - invalid in .php config + ], + ], + ], +]; diff --git a/e2e/bad-exclude-paths/phpneon2.php b/e2e/bad-exclude-paths/phpneon2.php new file mode 100644 index 0000000000..4c06f1f310 --- /dev/null +++ b/e2e/bad-exclude-paths/phpneon2.php @@ -0,0 +1,16 @@ + [ + __DIR__ . '/../../conf/bleedingEdge.neon', + ], + 'parameters' => [ + 'level' => '8', + 'paths' => [__DIR__ . '/src'], + 'excludePaths' => [ + 'analyse' => [ + 'src/test.php', // not absolute path - invalid in .php config + ], + ], + ], +]; diff --git a/src/DependencyInjection/ValidateExcludePathsExtension.php b/src/DependencyInjection/ValidateExcludePathsExtension.php index e98e512b31..cbc358607e 100644 --- a/src/DependencyInjection/ValidateExcludePathsExtension.php +++ b/src/DependencyInjection/ValidateExcludePathsExtension.php @@ -45,11 +45,13 @@ public function loadConfiguration(): void $errors = []; foreach (array_unique($paths) as $path) { - if (is_dir($path)) { - continue; - } - if (is_file($path)) { - continue; + if (FileExcluder::isAbsolutePath($path)) { + if (is_dir($path)) { + continue; + } + if (is_file($path)) { + continue; + } } if (FileExcluder::isFnmatchPattern($path)) { continue; diff --git a/src/DependencyInjection/ValidateIgnoredErrorsExtension.php b/src/DependencyInjection/ValidateIgnoredErrorsExtension.php index 572e7c6dcd..c4635af70a 100644 --- a/src/DependencyInjection/ValidateIgnoredErrorsExtension.php +++ b/src/DependencyInjection/ValidateIgnoredErrorsExtension.php @@ -151,11 +151,13 @@ public function getRegistry(): OperatorTypeSpecifyingExtensionRegistry } foreach ($ignorePaths as $ignorePath) { - if (is_dir($ignorePath)) { - continue; - } - if (is_file($ignorePath)) { - continue; + if (FileExcluder::isAbsolutePath($ignorePath)) { + if (is_dir($ignorePath)) { + continue; + } + if (is_file($ignorePath)) { + continue; + } } if (FileExcluder::isFnmatchPattern($ignorePath)) { continue; diff --git a/src/File/FileExcluder.php b/src/File/FileExcluder.php index 7ebf1aa20a..568f7f1bbb 100644 --- a/src/File/FileExcluder.php +++ b/src/File/FileExcluder.php @@ -9,6 +9,7 @@ use function preg_match; use function str_starts_with; use function strlen; +use function substr; use const DIRECTORY_SEPARATOR; use const FNM_CASEFOLD; use const FNM_NOESCAPE; @@ -119,6 +120,19 @@ public function isExcludedFromAnalysing(string $file): bool return false; } + public static function isAbsolutePath(string $path): bool + { + if (DIRECTORY_SEPARATOR === '/') { + if (str_starts_with($path, '/')) { + return true; + } + } elseif (substr($path, 1, 1) === ':') { + return true; + } + + return false; + } + public static function isFnmatchPattern(string $path): bool { return preg_match('~[*?[\]]~', $path) > 0;