3838 });
3939 });
4040
41+ describe ('canonicalizePath() ' , function () {
42+ test ('resolves relative dot-dot traversals out of vendor directory ' , function () {
43+ $ rawComposerPath = 'vendor/composer/../../tests/Fixtures/Generics/Producer.php ' ;
44+ expect (PathMatcher::canonicalizePath ($ rawComposerPath ))
45+ ->toBe ('tests/Fixtures/Generics/Producer.php ' )
46+ ;
47+ });
48+
49+ test ('resolves Windows backslash dot-dot traversals ' , function () {
50+ $ windowsPath = 'C: \\project \\vendor \\composer \\.. \\.. \\src \\Service.php ' ;
51+ expect (PathMatcher::canonicalizePath ($ windowsPath ))
52+ ->toBe ('C:/project/src/Service.php ' )
53+ ;
54+ });
55+
56+ test ('resolves absolute Unix paths with dot-dot segments ' , function () {
57+ $ absolutePath = '/var/www/html/app/../src/Core/Util.php ' ;
58+ expect (PathMatcher::canonicalizePath ($ absolutePath ))
59+ ->toBe ('/var/www/html/src/Core/Util.php ' )
60+ ;
61+ });
62+
63+ test ('returns normalized path untouched when no dot-dot segments exist ' , function () {
64+ $ cleanPath = 'src/Controller/WebController.php ' ;
65+ expect (PathMatcher::canonicalizePath ($ cleanPath ))->toBe ($ cleanPath );
66+ });
67+
68+ test ('handles deep multi-level dot-dot resolution cleanly ' , function () {
69+ expect (PathMatcher::canonicalizePath ('a/b/c/d/../../e ' ))->toBe ('a/b/e ' )
70+ ->and (PathMatcher::canonicalizePath ('a/b/../../c ' ))->toBe ('c ' )
71+ ;
72+ });
73+ });
74+
4175 describe ('isVendorPath() ' , function () {
4276 test ('identifies absolute and relative vendor paths correctly ' , function () {
4377 expect (PathMatcher::isVendorPath ('vendor/doctrine/dbal/src/Schema.php ' ))->toBeTrue ()
5286 ;
5387 });
5488
89+ test ('does not classify relative paths traversing OUT of vendor as vendor paths ' , function () {
90+ $ composerRelativeTestPath = 'vendor/composer/../../tests/Fixtures/Generics/Producer.php ' ;
91+ expect (PathMatcher::isVendorPath ($ composerRelativeTestPath ))->toBeFalse ();
92+ });
93+
5594 test ('does not falsely classify application directories with vendor prefix as vendor directory ' , function () {
5695 expect (PathMatcher::isVendorPath ('vendor-tools/Deploy.php ' ))->toBeFalse ()
5796 ->and (PathMatcher::isVendorPath ('vendor_custom/Helper.php ' ))->toBeFalse ()
165204 ->and (PathMatcher::mayPathBeIncluded ('src/App/Controller.php ' ))->toBeTrue ()
166205 ;
167206 });
207+
208+ test ('correctly handles relative dot-dot paths traversing out of vendor into included directories ' , function () {
209+ Config::set ([
210+ 'include ' => ['src/** ' , 'tests/** ' ],
211+ 'exclude ' => ['vendor/** ' ],
212+ ]);
213+
214+ $ traversalPath = 'vendor/composer/../../tests/Fixtures/Generics/Producer.php ' ;
215+
216+ expect (PathMatcher::mayPathBeIncluded ($ traversalPath ))->toBeTrue ();
217+ });
168218 });
169219
170220 describe ('compileGlobToRegex() ' , function () {
274324 expect (true )->toBeTrue ();
275325 });
276326 });
277- });
327+ });
0 commit comments