diff --git a/Imagine/Filter/Loader/AutoRotateFilterLoader.php b/Imagine/Filter/Loader/AutoRotateFilterLoader.php index dfc2dd92a..e702e79f4 100644 --- a/Imagine/Filter/Loader/AutoRotateFilterLoader.php +++ b/Imagine/Filter/Loader/AutoRotateFilterLoader.php @@ -3,6 +3,7 @@ namespace Liip\ImagineBundle\Imagine\Filter\Loader; use Imagine\Image\ImageInterface; +use Imagine\Exception\InvalidArgumentException; /** * AutoRotateFilterLoader - rotates an Image based on its EXIF Data. @@ -22,6 +23,12 @@ class AutoRotateFilterLoader implements LoaderInterface public function load(ImageInterface $image, array $options = array()) { if ($orientation = $this->getOrientation($image)) { + if ($orientation < 1 || $orientation > 8) { + throw new InvalidArgumentException( + sprintf('The image has wrong EXIF orientation tag (%d)', $orientation) + ); + } + // Rotates if necessary. $degree = $this->calculateRotation($orientation); if ($degree !== 0) { @@ -59,8 +66,6 @@ private function calculateRotation($orientation) case 7: case 8: return -90; - default: - throw new Exception('Unhandled orientation'); } } @@ -112,9 +117,6 @@ private function isFlipped($orientation) case 5: case 7: return true; - - default: - throw new Exception('Unhandled orientation'); } } } diff --git a/Tests/Fixtures/assets/pixel_1x1_orientation_at_0x30.jpg b/Tests/Fixtures/assets/pixel_1x1_orientation_at_0x30.jpg new file mode 100644 index 000000000..4348d4cac Binary files /dev/null and b/Tests/Fixtures/assets/pixel_1x1_orientation_at_0x30.jpg differ diff --git a/Tests/Imagine/Filter/Loader/AutoRotateFilterLoaderTest.php b/Tests/Imagine/Filter/Loader/AutoRotateFilterLoaderTest.php index feaae7252..9f711a19e 100644 --- a/Tests/Imagine/Filter/Loader/AutoRotateFilterLoaderTest.php +++ b/Tests/Imagine/Filter/Loader/AutoRotateFilterLoaderTest.php @@ -26,30 +26,42 @@ private function loadExif($exifValue, $expectCallRotateValue, $expectCallFlip) { $loader = new AutoRotateFilterLoader(); - // Mocks the metadata and makes it return the expected exif value for the rotation. - // If $exifValue is null, it means the image doesn't contain any metadata. - $metaData = $this->getMockMetaData(); + // Mocks the image and makes it use the fake meta data. + $image = $this->getMockImage(); - $metaData - ->expects($this->atLeastOnce()) - ->method('offsetGet') - ->willReturn($exifValue); + if (method_exists('Imagine\Image\ImageInterface', 'metadata')) { + // Mocks the metadata and makes it return the expected exif value for the rotation. + // If $exifValue is null, it means the image doesn't contain any metadata. + $metaData = $this->getMockMetaData(); - if ($exifValue && $exifValue !== '1') { $metaData + ->expects($this->atLeastOnce()) + ->method('offsetGet') + ->willReturn($exifValue); + + if ($exifValue && $exifValue > '1' && $exifValue <= 8) { + $metaData + ->expects($this->once()) + ->method('offsetSet') + ->with($this->orientationKey, '1'); + } + + $image + ->expects($this->atLeastOnce()) + ->method('metadata') + ->willReturn($metaData); + } else { + $jpg = file_get_contents(__DIR__.'/../../../Fixtures/assets/pixel_1x1_orientation_at_0x30.jpg'); + // The byte with orientation is at offset 0x30 for this image + $jpg[0x30] = chr((int) $exifValue); + + $image ->expects($this->once()) - ->method('offsetSet') - ->with($this->orientationKey, '1'); + ->method('get') + ->with('jpg') + ->will($this->returnValue($jpg)); } - // Mocks the image and makes it use the fake meta data. - $image = $this->getMockImage(); - - $image - ->expects($this->atLeastOnce()) - ->method('metadata') - ->willReturn($metaData); - // Checks that rotate is called with $expectCallRotateValue, or not called at all if $expectCallRotateValue is null. $image ->expects($expectCallRotateValue !== null ? $this->once() : $this->never()) @@ -138,7 +150,18 @@ public function testLoadExif7() */ public function testLoadExif8() { - $this->loadExif('8', null - 90, false); + $this->loadExif('8', -90, false); + } + + /** + * Theoretically Orientation is `short` (uint16), so it could be anything + * from [0; 65535]. + * + * @expectedException \Imagine\Exception\InvalidArgumentException + */ + public function testLoadExifInvalid() + { + $this->loadExif('10', null, false); } /**