Skip to content

Commit e9bcfd7

Browse files
committed
[Filesystem] Unify logic for isAbsolute() in Path
1 parent edcbb76 commit e9bcfd7

File tree

3 files changed

+36
-43
lines changed

3 files changed

+36
-43
lines changed

Filesystem.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -576,17 +576,11 @@ public function mirror(string $originDir, string $targetDir, ?\Traversable $iter
576576
}
577577

578578
/**
579-
* Returns whether the file path is an absolute path.
579+
* Returns whether the given path is absolute.
580580
*/
581581
public function isAbsolutePath(string $file): bool
582582
{
583-
return '' !== $file && (strspn($file, '/\\', 0, 1)
584-
|| (\strlen($file) > 3 && ctype_alpha($file[0])
585-
&& ':' === $file[1]
586-
&& strspn($file, '/\\', 2, 1)
587-
)
588-
|| null !== parse_url($file, \PHP_URL_SCHEME)
589-
);
583+
return Path::isAbsolute($file);
590584
}
591585

592586
/**

Path.php

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -358,38 +358,18 @@ public static function changeExtension(string $path, string $extension): string
358358
return substr($path, 0, -\strlen($actualExtension)).$extension;
359359
}
360360

361+
/**
362+
* Returns whether the given path is absolute.
363+
*/
361364
public static function isAbsolute(string $path): bool
362365
{
363-
if ('' === $path) {
364-
return false;
365-
}
366-
367-
// Strip scheme
368-
if (false !== ($schemeSeparatorPosition = strpos($path, '://')) && 1 !== $schemeSeparatorPosition) {
369-
$path = substr($path, $schemeSeparatorPosition + 3);
370-
}
371-
372-
$firstCharacter = $path[0];
373-
374-
// UNIX root "/" or "\" (Windows style)
375-
if ('/' === $firstCharacter || '\\' === $firstCharacter) {
376-
return true;
377-
}
378-
379-
// Windows root
380-
if (\strlen($path) > 1 && ctype_alpha($firstCharacter) && ':' === $path[1]) {
381-
// Special case: "C:"
382-
if (2 === \strlen($path)) {
383-
return true;
384-
}
385-
386-
// Normal case: "C:/ or "C:\"
387-
if ('/' === $path[2] || '\\' === $path[2]) {
388-
return true;
389-
}
390-
}
391-
392-
return false;
366+
return '' !== $path && (strspn($path, '/\\', 0, 1)
367+
|| (\strlen($path) > 3 && ctype_alpha($path[0])
368+
&& ':' === $path[1]
369+
&& strspn($path, '/\\', 2, 1)
370+
)
371+
|| null !== parse_url($path, \PHP_URL_SCHEME)
372+
);
393373
}
394374

395375
public static function isRelative(string $path): bool

Tests/PathTest.php

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -364,31 +364,50 @@ public function testChangeExtension(string $path, string $extension, string $pat
364364

365365
public static function provideIsAbsolutePathTests(): \Generator
366366
{
367+
// UNIX-style absolute paths
367368
yield ['/css/style.css', true];
368369
yield ['/', true];
369370
yield ['css/style.css', false];
370371
yield ['', false];
371372

373+
// UNIX-style absolute paths with backslashes
372374
yield ['\\css\\style.css', true];
373375
yield ['\\', true];
374376
yield ['css\\style.css', false];
375377

378+
// Windows-style absolute paths
376379
yield ['C:/css/style.css', true];
377380
yield ['D:/', true];
378381
yield ['C:///windows', true];
379382
yield ['C://test', true];
380383

384+
// Windows-style absolute paths with backslashes
381385
yield ['E:\\css\\style.css', true];
382386
yield ['F:\\', true];
383387

388+
// Windows special case (drive only)
389+
yield ['C:', true];
390+
391+
// URLs and stream wrappers are considered absolute
384392
yield ['phar:///css/style.css', true];
385393
yield ['phar:///', true];
394+
yield ['http://example.com', true];
395+
yield ['ftp://user@server/path', true];
396+
yield ['vfs://root/file.txt', true];
397+
398+
// "C:" without a slash is treated as a scheme by parse_url()
399+
yield ['C:css/style.css', true];
400+
401+
// Relative paths
402+
yield ['/var/lib', true];
403+
yield ['c:\\\\var\\lib', true]; // c:\\var\lib
404+
yield ['\\var\\lib', true];
405+
yield ['var/lib', false];
406+
yield ['../var/lib', false];
407+
yield ['', false];
386408

387-
// Windows special case
388-
yield ['C:', true];
389-
390-
// Not considered absolute
391-
yield ['C:css/style.css', false];
409+
// Empty path
410+
yield ['', false];
392411
}
393412

394413
/**

0 commit comments

Comments
 (0)