Skip to content

Commit 7140d1f

Browse files
Canonicalize source filter paths to resolve relative segments
When phpunit.xml is in a subdirectory and uses relative paths with ".." (e.g. ../src/), the path was passed to the file filter without canonicalization, causing the generated regex to include literal ".." segments that never match resolved file paths. Apply realpath() in FileFilterMapper to normalize directory and file paths before building the filter.
1 parent 75fb981 commit 7140d1f

2 files changed

Lines changed: 63 additions & 2 deletions

File tree

src/TextUI/Configuration/FileFilterMapper.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010
namespace PHPUnit\TextUI\Configuration;
1111

12+
use function realpath;
1213
use SebastianBergmann\FileFilter\Builder as FilterBuilder;
1314
use SebastianBergmann\FileFilter\Filter as FileFilter;
1415

@@ -37,8 +38,10 @@ private function directories(FilterDirectoryCollection $directories): array
3738
$result = [];
3839

3940
foreach ($directories as $directory) {
41+
$path = realpath($directory->path());
42+
4043
$result[] = [
41-
'path' => $directory->path(),
44+
'path' => $path !== false ? $path : $directory->path(),
4245
'prefix' => $directory->prefix(),
4346
'suffix' => $directory->suffix(),
4447
];
@@ -55,7 +58,9 @@ private function files(FilterFileCollection $files): array
5558
$result = [];
5659

5760
foreach ($files as $file) {
58-
$result[] = $file->path();
61+
$path = realpath($file->path());
62+
63+
$result[] = $path !== false ? $path : $file->path();
5964
}
6065

6166
return $result;

tests/unit/TextUI/SourceFilterTest.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,62 @@ public static function provider(): array
514514
),
515515
),
516516
],
517+
'file included using directory with non-canonical path' => [
518+
[
519+
self::fixturePath('a/PrefixSuffix.php') => true,
520+
],
521+
self::createSource(
522+
includeDirectories: FilterDirectoryCollection::fromArray(
523+
[
524+
new FilterDirectory(self::fixturePath('/b/../a'), '', '.php'),
525+
],
526+
),
527+
),
528+
],
529+
'file included using file with non-canonical path' => [
530+
[
531+
self::fixturePath('a/PrefixSuffix.php') => true,
532+
],
533+
self::createSource(includeFiles: FilterFileCollection::fromArray(
534+
[
535+
new FilterFile(self::fixturePath('/b/../a/PrefixSuffix.php')),
536+
],
537+
)),
538+
],
539+
'file excluded using directory with non-canonical path' => [
540+
[
541+
self::fixturePath('a/PrefixSuffix.php') => false,
542+
],
543+
self::createSource(
544+
includeDirectories: FilterDirectoryCollection::fromArray(
545+
[
546+
new FilterDirectory(self::fixturePath(), '', '.php'),
547+
],
548+
),
549+
excludeDirectories: FilterDirectoryCollection::fromArray(
550+
[
551+
new FilterDirectory(self::fixturePath('/b/../a'), '', '.php'),
552+
],
553+
),
554+
),
555+
],
556+
'file excluded using file with non-canonical path' => [
557+
[
558+
self::fixturePath('a/PrefixSuffix.php') => false,
559+
],
560+
self::createSource(
561+
includeDirectories: FilterDirectoryCollection::fromArray(
562+
[
563+
new FilterDirectory(self::fixturePath(), '', '.php'),
564+
],
565+
),
566+
excludeFiles: FilterFileCollection::fromArray(
567+
[
568+
new FilterFile(self::fixturePath('/b/../a/PrefixSuffix.php')),
569+
],
570+
),
571+
),
572+
],
517573
'files included using same directory and different prefixes' => [
518574
[
519575
self::fixturePath('a/c/Suffix.php') => true,

0 commit comments

Comments
 (0)