From ef1a9ce3b13b0744ad155a17f16d7873ce7c2b1b Mon Sep 17 00:00:00 2001 From: Diogo Peralta Cordeiro Date: Sat, 14 Aug 2021 15:00:40 +0100 Subject: [PATCH] [ImageEncoder] Handle VIPS unsupported image type --- .../UnsupportedFileTypeException.php | 19 ++++++ plugins/ImageEncoder/ImageEncoder.php | 64 +++++++++++++++---- 2 files changed, 69 insertions(+), 14 deletions(-) create mode 100644 plugins/ImageEncoder/Exception/UnsupportedFileTypeException.php diff --git a/plugins/ImageEncoder/Exception/UnsupportedFileTypeException.php b/plugins/ImageEncoder/Exception/UnsupportedFileTypeException.php new file mode 100644 index 0000000000..97f9d6c089 --- /dev/null +++ b/plugins/ImageEncoder/Exception/UnsupportedFileTypeException.php @@ -0,0 +1,19 @@ + - * @authir Hugo Sales + * @author Hugo Sales * * @copyright 2021 Free Software Foundation, Inc http://www.fsf.org * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ class ImageEncoder extends Plugin { + public function version(): string + { + return '3.0.0'; + } + /** * Several obscure file types should be normalized to WebP on resize. */ @@ -62,12 +69,13 @@ class ImageEncoder extends Plugin * * @param SplFileInfo $file * @param null|string $mimetype in/out - * @param null|string $title in/out * @param null|int $width out * @param null|int $height out * - * @throws Vips\Exception + * @throws ClientException When vips doesn't understand the given mimetype + * @throws ServerException * @throws TemporaryFileException + * @throws Vips\Exception * * @return bool */ @@ -81,19 +89,24 @@ class ImageEncoder extends Plugin // Try to maintain original mimetype extension, otherwise default to preferred. $extension = image_type_to_extension($this->preferredType(), include_dot: true); - GSFile::ensureFilenameWithProperExtension( + $extension = GSFile::ensureFilenameWithProperExtension( title: $file->getFilename(), mimetype: $original_mimetype, ext: $extension, force: false - ); + ) ?? $extension; // TemporaryFile handles deleting the file if some error occurs // IMPORTANT: We have to specify the extension for the temporary file // in order to have a format conversion $temp = new TemporaryFile(['prefix' => 'image', 'suffix' => $extension]); - $image = Vips\Image::newFromFile($file->getRealPath(), ['access' => 'sequential']); + try { + $image = Vips\Image::newFromFile($file->getRealPath(), ['access' => 'sequential']); + } catch (Vips\Exception $e) { + Log::debug("ImageEncoder's Vips couldn't handle the image file, failed with {$e}."); + throw new UnsupportedFileTypeException(_m("Unsupported image file with {$mimetype}.", previous: $e)); + } $width = Common::clamp($image->width, 0, Common::config('attachments', 'max_width')); $height = Common::clamp($image->height, 0, Common::config('attachments', 'max_height')); $image = $image->crop(0, 0, $width, $height); @@ -102,6 +115,7 @@ class ImageEncoder extends Plugin // Replace original file with the sanitized one $temp->commit($file->getRealPath()); + // Only one plugin can handle sanitization return Event::stop; } @@ -143,13 +157,14 @@ class ImageEncoder extends Plugin * enable the handling of bigger images, which can cause a peak of memory consumption, while * encoding * - * @param Attachment $attachment - * @param AttachmentThumbnail $thumbnail - * @param int $width - * @param int $height - * @param bool $crop + * @param string $source + * @param null|TemporaryFile $destination + * @param int $width + * @param int $height + * @param bool $smart_crop + * @param null|string $mimetype * - * @throws Exception + * @throws TemporaryFileException * @throws Vips\Exception * * @return bool @@ -193,4 +208,25 @@ class ImageEncoder extends Plugin } return Event::stop; } + + /** + * Event raised when GNU social polls the plugin for information about it. + * Adds this plugin's version information to $versions array + * + * @param &$versions array inherited from parent + * + * @return bool true hook value + */ + public function onPluginVersion(array &$versions): bool + { + $versions[] = [ + 'name' => 'ImageEncoder', + 'version' => $this->version(), + 'author' => 'Hugo Sales, Diogo Peralta Cordeiro', + 'homepage' => GNUSOCIAL_PROJECT_URL, + 'description' => // TRANS: Plugin description. + _m('Use VIPS for some additional image support.'), + ]; + return Event::next; + } }