From 22b7be20b5a1bafb9430b320092d210dac724284 Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Thu, 19 Oct 2023 19:51:35 +0200 Subject: [PATCH] Prevent copy and move to same destinations as the source. --- src/Filesystem.php | 27 +++++++++++++++++---------- src/FilesystemTest.php | 20 ++++++++++++++++++++ src/UnableToCopyFile.php | 14 ++++++++++++++ src/UnableToMoveFile.php | 18 ++++++++++++++++++ 4 files changed, 69 insertions(+), 10 deletions(-) diff --git a/src/Filesystem.php b/src/Filesystem.php index 94fae15ef..9bac9809a 100644 --- a/src/Filesystem.php +++ b/src/Filesystem.php @@ -119,20 +119,27 @@ private function pipeListing(string $location, bool $deep, iterable $listing): G public function move(string $source, string $destination, array $config = []): void { - $this->adapter->move( - $this->pathNormalizer->normalizePath($source), - $this->pathNormalizer->normalizePath($destination), - $this->config->extend($config) - ); + $from = $this->pathNormalizer->normalizePath($source); + $to = $this->pathNormalizer->normalizePath($destination); + + if ($from === $to) { + throw UnableToMoveFile::sourceAndDestinationAreTheSame($source, $destination); + throw UnableToMoveFile::because('Source and destination are the same', $source, $destination); + } + + $this->adapter->move($from, $to, $this->config->extend($config)); } public function copy(string $source, string $destination, array $config = []): void { - $this->adapter->copy( - $this->pathNormalizer->normalizePath($source), - $this->pathNormalizer->normalizePath($destination), - $this->config->extend($config) - ); + $from = $this->pathNormalizer->normalizePath($source); + $to = $this->pathNormalizer->normalizePath($destination); + + if ($from === $to) { + throw UnableToCopyFile::sourceAndDestinationAreTheSame($source, $destination); + } + + $this->adapter->copy($from, $to, $this->config->extend($config)); } public function lastModified(string $path): int diff --git a/src/FilesystemTest.php b/src/FilesystemTest.php index e7ae891ed..46a7fd6e9 100644 --- a/src/FilesystemTest.php +++ b/src/FilesystemTest.php @@ -480,6 +480,26 @@ public function publicUrl(string $path, Config $config): string self::assertSame('custom/file.txt', $filesystem->publicUrl('file.txt')); } + /** + * @test + */ + public function copying_from_and_to_the_same_location_fails(): void + { + $this->expectExceptionObject(UnableToMoveFile::sourceAndDestinationAreTheSame('from.txt', 'from.txt')); + + $this->filesystem->move('from.txt', 'from.txt'); + } + + /** + * @test + */ + public function moving_from_and_to_the_same_location_fails(): void + { + $this->expectExceptionObject(UnableToCopyFile::sourceAndDestinationAreTheSame('from.txt', 'from.txt')); + + $this->filesystem->copy('from.txt', 'from.txt'); + } + /** * @test */ diff --git a/src/UnableToCopyFile.php b/src/UnableToCopyFile.php index 2180c1e36..a27d66e48 100644 --- a/src/UnableToCopyFile.php +++ b/src/UnableToCopyFile.php @@ -41,6 +41,20 @@ public static function fromLocationTo( return $e; } + public static function sourceAndDestinationAreTheSame(string $source, string $destination): UnableToCopyFile + { + return UnableToCopyFile::because('Source and destination are the same', $source, $destination); + } + + public static function because(string $reason, string $sourcePath, string $destinationPath): UnableToCopyFile + { + $e = new static("Unable to copy file from $sourcePath to $destinationPath, because $reason"); + $e->source = $sourcePath; + $e->destination = $destinationPath; + + return $e; + } + public function operation(): string { return FilesystemOperationFailed::OPERATION_COPY; diff --git a/src/UnableToMoveFile.php b/src/UnableToMoveFile.php index 72792f4ab..f5c68097c 100644 --- a/src/UnableToMoveFile.php +++ b/src/UnableToMoveFile.php @@ -19,6 +19,11 @@ final class UnableToMoveFile extends RuntimeException implements FilesystemOpera */ private $destination; + public static function sourceAndDestinationAreTheSame(string $source, string $destination): UnableToMoveFile + { + return UnableToMoveFile::because('Source and destination are the same', $source, $destination); + } + public function source(): string { return $this->source; @@ -42,6 +47,19 @@ public static function fromLocationTo( return $e; } + public static function because( + string $reason, + string $sourcePath, + string $destinationPath, + ): UnableToMoveFile { + $message = "Unable to move file from $sourcePath to $destinationPath, because $reason"; + $e = new static($message); + $e->source = $sourcePath; + $e->destination = $destinationPath; + + return $e; + } + public function operation(): string { return FilesystemOperationFailed::OPERATION_MOVE;