Make WordPress Core

Changeset 49174


Ignore:
Timestamp:
10/16/2020 10:46:58 AM (4 years ago)
Author:
mikeschroder
Message:

Media: Work around use-cropbox bug in Ghostscript 8.70

Wraps Imagick::readImage() for PDFs with exception handling, trying again without use-cropbox if this fails.

Introduces WP_Image_Editor_Imagick::pdf_load_source().

Works around a known issue in Ghostscript 8.70 (fixed in 8.71) that results in a stack underflow.
While it only affects this version, it remains a common version found on hosts, and prevented some PDF thumbnails from being generated.

See this Ghostscript bug for more details: https://bugs.ghostscript.com/show_bug.cgi?id=690676

Props azaozz, joseaneto, cranewest, dantahoua, n5hzr, mikeschroder.
Fixes #48853.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-image-editor-imagick.php

    r48798 r49174  
    141141            $this->image    = new Imagick();
    142142            $file_extension = strtolower( pathinfo( $this->file, PATHINFO_EXTENSION ) );
    143             $filename       = $this->file;
    144143
    145144            if ( 'pdf' === $file_extension ) {
    146                 $filename = $this->pdf_setup();
    147             }
    148 
    149             // Reading image after Imagick instantiation because `setResolution`
    150             // only applies correctly before the image is read.
    151             $this->image->readImage( $filename );
     145                $pdf_loaded = $this->pdf_load_source();
     146
     147                if ( is_wp_error( $pdf_loaded ) ) {
     148                    return $pdf_loaded;
     149                }
     150            } else {
     151                $this->image->readImage( $this->file );
     152            }
    152153
    153154            if ( ! $this->image->valid() ) {
     
    166167
    167168        $updated_size = $this->update_size();
     169
    168170        if ( is_wp_error( $updated_size ) ) {
    169171            return $updated_size;
     
    796798            $this->image->setResolution( 128, 128 );
    797799
     800            // Only load the first page.
     801            return $this->file . '[0]';
     802        } catch ( Exception $e ) {
     803            return new WP_Error( 'pdf_setup_failed', $e->getMessage(), $this->file );
     804        }
     805    }
     806
     807    /**
     808     * Load the image produced by Ghostscript.
     809     *
     810     * Includes a workaround for a bug in Ghostscript 8.70 that prevents processing of some PDF files
     811     * when `use-cropbox` is set.
     812     *
     813     * @since 5.6
     814     *
     815     * @return true|WP_error
     816     */
     817    protected function pdf_load_source() {
     818        $filename = $this->pdf_setup();
     819
     820        if ( is_wp_error( $filename ) ) {
     821            return $filename;
     822        }
     823
     824        try {
    798825            // When generating thumbnails from cropped PDF pages, Imagemagick uses the uncropped
    799826            // area (resulting in unnecessary whitespace) unless the following option is set.
    800827            $this->image->setOption( 'pdf:use-cropbox', true );
    801828
    802             // Only load the first page.
    803             return $this->file . '[0]';
    804         } catch ( Exception $e ) {
    805             return new WP_Error( 'pdf_setup_failed', $e->getMessage(), $this->file );
    806         }
     829            // Reading image after Imagick instantiation because `setResolution`
     830            // only applies correctly before the image is read.
     831            $this->image->readImage( $filename );
     832        } catch ( Exception $e ) {
     833            // Attempt to run `gs` without the `use-cropbox` option. See #48853.
     834            $this->image->setOption( 'pdf:use-cropbox', false );
     835
     836            $this->image->readImage( $filename );
     837        }
     838
     839        return true;
    807840    }
    808841
Note: See TracChangeset for help on using the changeset viewer.