diff --git a/src/Exceptions/ImageNotFoundOrReadableException.php b/src/Exceptions/ImageNotFoundOrReadableException.php new file mode 100755 index 0000000..e2acb09 --- /dev/null +++ b/src/Exceptions/ImageNotFoundOrReadableException.php @@ -0,0 +1,11 @@ +getOutputFormat($extension, $format); $thumbnailPath = $this->getThumbnailDir($path) . $thumbnailFileName; - // $geometry = GeometryOld::parseGeometry($params); $geometry = new Geometry($params); if (!$this->thumbnailExists($thumbnailPath)) { try { $thumbnail = $this->processImage($sourceImagePath, $geometry); } catch (RuntimeException $e) { - throw new Exception('Unable to open image - wrong permissions, empty or corrupted.'); + throw new ImageNotFoundOrReadableException('Unable to open image - wrong permissions, empty or corrupted.'); } if ($this->config->strip) { @@ -104,13 +105,13 @@ public function getSourceImagePath(string $path): string { $fullPath = (string) realpath($this->config->wwwDir . DIRECTORY_SEPARATOR . $path); - if (!is_file($fullPath)) { - throw new Exception('Source image not found or not readable.'); - } - // wonky, but better than nothing if (strpos($path, '../') !== false) { - throw new Exception('Attempt to access files outside permitted path.'); + throw new SecurityException('Attempt to access files outside permitted path.'); + } + + if (!is_file($fullPath)) { + throw new ImageNotFoundOrReadableException('Source image not found or not readable.'); } return $fullPath; diff --git a/tests/ResizerTest.php b/tests/ResizerTest.php new file mode 100755 index 0000000..dd47f63 --- /dev/null +++ b/tests/ResizerTest.php @@ -0,0 +1,92 @@ +config = new ResizerConfig(); + $this->config->tempDir = __DIR__ . '/../temp'; + $this->config->wwwDir = __DIR__ . '/../tests'; + $this->config->qualityJpeg = 65; + $this->config->qualityWebp = 65; + $this->config->compressionPng = 9; + $this->config->library = 'Gd'; + + $this->resizer = new Resizer($this->config, false); + $this->image = 'test.png'; + } + + + // runs for every test + // public function setUp(): void + // { + // } + + + public function testImageNotFound(): void + { + Assert::exception( + function() {$this->resizer->getSourceImagePath('does_not_exist.jpg');}, + ImageNotFoundOrReadableException::class, + ); + } + + + public function testSecurityException(): void + { + Assert::exception( + function() {$this->resizer->getSourceImagePath('../../haxxor.png');}, + SecurityException::class, + ); + } + + + public function testImageFound(): void + { + Assert::equal( + __DIR__ . '/test.png', + $this->resizer->getSourceImagePath($this->image), + ); + } + + + public function testProcess(): void + { + Assert::same( + FileSystem::normalizePath(__DIR__ . '/../temp/resizer/test.png/200x.png'), + FileSystem::normalizePath($this->resizer->process($this->image, '200x')), + ); + } + + + public function tearDown() + { + FileSystem::delete($this->config->tempDir . $this->config->cache); + } +} + +$test = new ResizerTest; +$test->run(); diff --git a/tests/output/ResizerTest.[method=testProcess].actual b/tests/output/ResizerTest.[method=testProcess].actual new file mode 100644 index 0000000..7460ab3 --- /dev/null +++ b/tests/output/ResizerTest.[method=testProcess].actual @@ -0,0 +1 @@ +/home/users/devminion/minion.dev/web/_dev/packages/nelson/resizer/temp/resizer/test.png/200x.png \ No newline at end of file diff --git a/tests/output/ResizerTest.[method=testProcess].expected b/tests/output/ResizerTest.[method=testProcess].expected new file mode 100644 index 0000000..561af32 --- /dev/null +++ b/tests/output/ResizerTest.[method=testProcess].expected @@ -0,0 +1 @@ +/home/users/devminion/minion.dev/web/_dev/packages/nelson/resizer/tests/test.png \ No newline at end of file diff --git a/tests/test.png b/tests/test.png new file mode 100755 index 0000000..94017ea Binary files /dev/null and b/tests/test.png differ