From 3a99822b66d4723d47fa1ba8056b336670ec3504 Mon Sep 17 00:00:00 2001 From: unclexo Date: Sat, 28 Jan 2023 21:29:46 +0600 Subject: [PATCH] Test handle method returns false on invalid image content --- app/Jobs/ImageUploadAndResizingJob.php | 45 +++++++++++++++++++------- tests/Feature/JobTest.php | 15 +++++++++ 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/app/Jobs/ImageUploadAndResizingJob.php b/app/Jobs/ImageUploadAndResizingJob.php index 459ba20..10a8e90 100644 --- a/app/Jobs/ImageUploadAndResizingJob.php +++ b/app/Jobs/ImageUploadAndResizingJob.php @@ -2,6 +2,7 @@ namespace App\Jobs; + use Illuminate\Bus\Queueable; use Illuminate\Contracts\Filesystem\Filesystem; use Illuminate\Contracts\Queue\ShouldBeUnique; @@ -56,15 +57,17 @@ public function storage() */ public function handle() { - $path = 'fake-image-name.jpg'; - - if (! $this->isAllowedExtension($this->getExtensionFromMimeType())) { + if (! $this->isValidImage()) return false; - } - if (! $this->storage()->put($path, base64_decode($this->imageContent))) { + $path = sprintf( + "%s.%s", + bin2hex(random_bytes(16)), // Apply your algorithm + $this->getExtensionFromMimeType($this->mimeType) + ); + + if (! $this->storage()->put($path, base64_decode($this->imageContent))) return false; - } $paths = []; @@ -79,21 +82,41 @@ public function handle() return $paths; } - private function isAllowedExtension(string $extension) + private function isValidImage() { - return in_array($extension, $this->allowedExtension); + if ( + base64_encode(base64_decode($this->imageContent, true)) === $this->imageContent && + ($file = tmpfile()) && + fwrite($file, base64_decode($this->imageContent)) + ) { + $mimeType = mime_content_type(stream_get_meta_data($file)['uri']); + + fclose($file); + + $extensionFromContent = $this->getExtensionFromMimeType($mimeType); + + return $this->getExtensionFromMimeType($this->mimeType) === $extensionFromContent && + $this->isAllowedExtension($extensionFromContent); + } + + return false; } - private function getExtensionFromMimeType() + private function getExtensionFromMimeType(string $mimeType) { - if (! preg_match("/^[a-z]+\/[a-z0-9\.\+-]+$/", $this->mimeType)) + if (! preg_match("/^[a-z]+\/[a-z0-9\.\+-]+$/", $mimeType)) return false; - [, $extension] = explode('/', $this->mimeType); + [, $extension] = explode('/', $mimeType); return $extension; } + private function isAllowedExtension(string $extension) + { + return in_array($extension, $this->allowedExtension); + } + /** * Modify an absolute path for renaming image name with resolution key * diff --git a/tests/Feature/JobTest.php b/tests/Feature/JobTest.php index f22ae36..bfd419d 100644 --- a/tests/Feature/JobTest.php +++ b/tests/Feature/JobTest.php @@ -87,4 +87,19 @@ public function handle_method_returns_false_on_invalid_mime_type() $this->assertFalse($job->handle()); } + + /** @test */ + public function handle_method_returns_false_on_invalid_image_content() + { + $image = UploadedFile::fake() + ->image('image.jpg', 50, 50) + ->mimeType('image/jpeg'); + + Storage::fake('public'); + + // Note that the image content is NOT base64 encoded + $job = new ImageUploadAndResizingJob($image->getMimeType(), $image->getContent()); + + $this->assertFalse($job->handle()); + } }