Verified Commit 4e49b11a authored by Alex Pott's avatar Alex Pott
Browse files

Issue #2583041 by mondrake, fietserwin, claudiu.cristea, alexpott, smustgrave,...

Issue #2583041 by mondrake, fietserwin, claudiu.cristea, alexpott, smustgrave, catch: GD toolkit & operations should catch \Throwable to fail gracefully in case of errors
parent d532f6fd
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -127,8 +127,14 @@ public function apply($operation, array $arguments = []) {
      $this->logger->error("The selected image handling toolkit '@toolkit' can not process operation '@operation'.", ['@toolkit' => $this->getPluginId(), '@operation' => $operation]);
      return FALSE;
    }
    catch (\InvalidArgumentException $e) {
      $this->logger->warning($e->getMessage(), []);
    catch (\Throwable $t) {
      $this->logger->warning("The image toolkit '@toolkit' failed processing '@operation' for image '@image'. Reported error: @class - @message", [
        '@toolkit' => $this->getPluginId(),
        '@operation' => $operation,
        '@image' => $this->getSource(),
        '@class' => get_class($t),
        '@message' => $t->getMessage(),
      ]);
      return FALSE;
    }
  }
+3 −0
Original line number Diff line number Diff line
@@ -185,6 +185,9 @@ final public function apply(array $arguments) {
   *
   * @return bool
   *   TRUE if the operation was performed successfully, FALSE otherwise.
   *
   * @throws \RuntimeException
   *   If the operation can not be performed.
   */
  abstract protected function execute(array $arguments);

+69 −24
Original line number Diff line number Diff line
@@ -180,8 +180,33 @@ protected function load() {
      return FALSE;
    }

    // Invalidate the image object and return if there's no function to load the
    // image file.
    $function = 'imagecreatefrom' . image_type_to_extension($this->getType(), FALSE);
    if (function_exists($function) && $resource = $function($this->getSource())) {
    if (!function_exists($function)) {
      $this->logger->error("The image toolkit '@toolkit' can not process image '@image'.", [
        '@toolkit' => $this->getPluginId(),
        '@image' => $this->getSource(),
      ]);
      $this->preLoadInfo = NULL;
      return FALSE;
    }

    // Invalidate the image object and return if the load fails.
    try {
      $resource = $function($this->getSource());
    }
    catch (\Throwable $t) {
      $this->logger->error("The image toolkit '@toolkit' failed loading image '@image'. Reported error: @class - @message", [
        '@toolkit' => $this->getPluginId(),
        '@image' => $this->getSource(),
        '@class' => get_class($t),
        '@message' => $t->getMessage(),
      ]);
      $this->preLoadInfo = NULL;
      return FALSE;
    }

    $this->setResource($resource);
    if (imageistruecolor($resource)) {
      return TRUE;
@@ -204,8 +229,6 @@ protected function load() {
    }
    return (bool) $this->getResource();
  }
    return FALSE;
  }

  /**
   * {@inheritdoc}
@@ -236,16 +259,38 @@ public function save($destination) {
      return FALSE;
    }
    if ($this->getType() == IMAGETYPE_JPEG) {
      try {
        $success = $function($this->getResource(), $destination, $this->configFactory->get('system.image.gd')->get('jpeg_quality'));
      }
      catch (\Throwable $t) {
        $this->logger->error("The image toolkit '@toolkit' failed saving image '@image'. Reported error: @class - @message", [
          '@toolkit' => $this->getPluginId(),
          '@image' => $destination,
          '@class' => get_class($t),
          '@message' => $t->getMessage(),
        ]);
        $success = FALSE;
      }
    }
    else {
      // Image types that support alpha need to be saved accordingly.
      if (in_array($this->getType(), [IMAGETYPE_PNG, IMAGETYPE_WEBP], TRUE)) {
        imagealphablending($this->getResource(), FALSE);
        imagesavealpha($this->getResource(), TRUE);
      }
      try {
        $success = $function($this->getResource(), $destination);
      }
      catch (\Throwable $t) {
        $this->logger->error("The image toolkit '@toolkit' failed saving image '@image'. Reported error: @class - @message", [
          '@toolkit' => $this->getPluginId(),
          '@image' => $destination,
          '@class' => get_class($t),
          '@message' => $t->getMessage(),
        ]);
        $success = FALSE;
      }
    }
    // Move temporary local file to remote destination.
    if (isset($permanent_destination) && $success) {
      try {
+25 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\image_test\Plugin\ImageToolkit\Operation\test;

/**
 * An image toolkit operation that throws a \RuntimeException.
 *
 * @ImageToolkitOperation(
 *   id = "failing",
 *   toolkit = "test",
 *   operation = "failing",
 *   label = @Translation("An image toolkit operation that throws a \\RuntimeException"),
 *   description = @Translation("An image toolkit operation that throws a \\RuntimeException.")
 * )
 */
class Failing extends OperationBase {

  /**
   * {@inheritdoc}
   */
  public function execute(array $arguments) {
    throw new \RuntimeException('Ahem, this image operation failed');
  }

}
+1 −1
Original line number Diff line number Diff line
@@ -258,7 +258,7 @@ protected static function supportedTypes() {
   */
  public function apply($operation, array $arguments = []) {
    $this->logCall('apply', func_get_args());
    return TRUE;
    return parent::apply($operation, $arguments);
  }

}
Loading