Skip to content

Commit

Permalink
Drop Windows support in RealPath filter
Browse files Browse the repository at this point in the history
Signed-off-by: ramchale <[email protected]>
  • Loading branch information
ramchale committed Nov 13, 2024
1 parent eadfd3a commit 5a51a0c
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 71 deletions.
8 changes: 8 additions & 0 deletions docs/book/v3/migration/v2-to-v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,14 @@ The following methods have been removed:

The constructor now only accepts an associative array of [documented options](../standard-filters.md#realPath).

`false` is no longer returned when the path must exist and does not.
Instead, the original value is returned.
Filters are not intended to provide validation.
So, to check if the path exists, ensure a validator (such as `Laminas\Validator\File\Exists') is also used.

Windows support has been dropped.
Which in some cases may now need a custom filter to handle Windows specific issues.

#### `SeparatorToCamelCase`

The constructor now only accepts an associative array of [documented options](../word.md#separatorToCamelCase).
Expand Down
19 changes: 8 additions & 11 deletions docs/book/v3/standard-filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -1125,8 +1125,7 @@ For more complex usage, read the

## RealPath

This filter will resolve given links and pathnames, and returns the canonicalized
absolute pathnames.
This filter will resolve given links and pathnames, and returns the canonicalized absolute pathnames.

### Supported Options

Expand All @@ -1137,13 +1136,12 @@ The following options are supported for `Laminas\Filter\RealPath`:

### Basic Usage

For any given link or pathname, its absolute path will be returned. References
to `/./`, `/../` and extra `/` sequences in the input path will be stripped. The
resulting path will not have any symbolic links, `/./`, or `/../` sequences.
For any given link or pathname, its absolute path will be returned.
References to `/./`, `/../` and extra `/` sequences in the input path will be stripped.
The resulting path will not have any symbolic links, `/./`, or `/../` sequences.

`Laminas\Filter\RealPath` will return `FALSE` on failure, e.g. if the file does not exist. On BSD
systems `Laminas\Filter\RealPath` doesn't fail if only the last path component doesn't exist, while
other systems will return `FALSE`.
`Laminas\Filter\RealPath` will return `FALSE` on failure, e.g. if the file does not exist.
On BSD systems `Laminas\Filter\RealPath` doesn't fail if only the last path component doesn't exist, while other systems will return `false`.

```php
$filter = new Laminas\Filter\RealPath();
Expand All @@ -1155,9 +1153,8 @@ $filtered = $filter->filter($path);

### Non-Existing Paths

Sometimes it is useful to get paths to files that do n0t exist; e.g., when you
want to get the real path for a path you want to create. You can then
provide a `FALSE` `exists` option at initiation.
Sometimes it is useful to get paths to files that do not exist; e.g., when you want to get the real path for a path you want to create.
You can then provide `false` for the `exists` option during construction.

```php
$filter = new Laminas\Filter\RealPath(['exists' => false]);
Expand Down
59 changes: 8 additions & 51 deletions src/RealPath.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,15 @@

namespace Laminas\Filter;

use Laminas\Stdlib\ErrorHandler;

use function array_pop;
use function explode;
use function getcwd;
use function implode;
use function file_exists;
use function is_string;
use function preg_match;
use function preg_replace;
use function realpath;
use function str_starts_with;
use function stripos;
use function substr;

use const DIRECTORY_SEPARATOR;
use const PHP_OS;

/**
* @psalm-type Options = array{
* exists?: bool,
* }
* @implements FilterInterface<string|array<array-key, string|mixed>>
* @implements FilterInterface<string>
*/
final class RealPath implements FilterInterface
{
Expand All @@ -42,48 +29,18 @@ public function filter(mixed $value): mixed
if (! is_string($value)) {
return $value;
}
$path = (string) $value;

if ($this->pathMustExist) {
return realpath($path);
}

ErrorHandler::start();
$realpath = realpath($path);
ErrorHandler::stop();
if ($realpath !== false) {
return $realpath;
if ($this->pathMustExist && ! file_exists($value)) {
return $value;
}

$drive = '';
if (stripos(PHP_OS, 'WIN') === 0) {
$path = preg_replace('/[\\\\\/]/', DIRECTORY_SEPARATOR, $path);
if (preg_match('/([a-zA-Z]\:)(.*)/', $path, $matches)) {
[, $drive, $path] = $matches;
} else {
$cwd = getcwd();
$drive = substr($cwd, 0, 2);
if (! str_starts_with($path, DIRECTORY_SEPARATOR)) {
$path = substr($cwd, 3) . DIRECTORY_SEPARATOR . $path;
}
}
} elseif (! str_starts_with($path, DIRECTORY_SEPARATOR)) {
$path = getcwd() . DIRECTORY_SEPARATOR . $path;
}
$realpath = realpath($value);

$stack = [];
$parts = explode(DIRECTORY_SEPARATOR, $path);
foreach ($parts as $dir) {
if ($dir !== '' && $dir !== '.') {
if ($dir === '..') {
array_pop($stack);
} else {
$stack[] = $dir;
}
}
if ($realpath === false) {
return $value;
}

return $drive . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $stack);
return $realpath;
}

public function __invoke(mixed $value): mixed
Expand Down
10 changes: 1 addition & 9 deletions test/RealPathTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
use PHPUnit\Framework\TestCase;
use stdClass;

use function str_contains;

use const DIRECTORY_SEPARATOR;
use const PHP_OS;

class RealPathTest extends TestCase
{
Expand All @@ -26,7 +23,6 @@ public function testFileExists(): void
$filename = __DIR__ . '/_files/file.1';
$result = $filter->filter($filename);

self::assertIsString($result);
self::assertStringContainsString($filename, $result);
}

Expand All @@ -38,11 +34,7 @@ public function testFileNonexistent(): void
$filter = new RealPathFilter();

$path = '/path/to/nonexistent';
if (str_contains(PHP_OS, 'BSD')) {
self::assertSame($path, $filter->filter($path));
} else {
self::assertSame(false, $filter->filter($path));
}
self::assertSame($path, $filter->filter($path));
}

public function testNonExistentPath(): void
Expand Down

0 comments on commit 5a51a0c

Please sign in to comment.