From f80e5d09197bfded72e74140bc377e0e96fc3622 Mon Sep 17 00:00:00 2001 From: antpb Date: Tue, 2 Feb 2021 16:53:04 +0000 Subject: [PATCH] Media: Avoid suppressing errors when using `getimagesize()`. Previously, all logic utilizing `getimagesize()` was supressing errors making it difficult to debug usage of the function. A new `wp_getimagesize()` function has been added to allow the errors to no longer be suppressed when `WP_DEBUG` is enabled. Props Howdy_McGee, SergeyBiryukov, mukesh27, davidbaumwald, noisysocks, hellofromTonya. Fixes #49889. Built from https://develop.svn.wordpress.org/trunk@50146 git-svn-id: http://core.svn.wordpress.org/trunk@49825 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/includes/ajax-actions.php | 2 +- .../includes/class-custom-image-header.php | 4 +- wp-admin/includes/class-wp-site-icon.php | 2 +- wp-admin/includes/image.php | 38 +++++++++++++++---- wp-includes/class-wp-image-editor-gd.php | 2 +- wp-includes/deprecated.php | 2 +- wp-includes/functions.php | 35 ++++++++++++++++- wp-includes/media.php | 4 +- wp-includes/version.php | 2 +- 9 files changed, 73 insertions(+), 18 deletions(-) diff --git a/wp-admin/includes/ajax-actions.php b/wp-admin/includes/ajax-actions.php index af8f053fe0..06c09f6e92 100644 --- a/wp-admin/includes/ajax-actions.php +++ b/wp-admin/includes/ajax-actions.php @@ -3927,7 +3927,7 @@ function wp_ajax_crop_image() { $parent_url = wp_get_attachment_url( $attachment_id ); $url = str_replace( wp_basename( $parent_url ), wp_basename( $cropped ), $parent_url ); - $size = @getimagesize( $cropped ); + $size = wp_getimagesize( $cropped ); $image_type = ( $size ) ? $size['mime'] : 'image/jpeg'; $object = array( diff --git a/wp-admin/includes/class-custom-image-header.php b/wp-admin/includes/class-custom-image-header.php index 6fb5460df9..76eddff973 100644 --- a/wp-admin/includes/class-custom-image-header.php +++ b/wp-admin/includes/class-custom-image-header.php @@ -791,7 +791,7 @@ endif; } if ( file_exists( $file ) ) { - list( $width, $height, $type, $attr ) = @getimagesize( $file ); + list( $width, $height, $type, $attr ) = wp_getimagesize( $file ); } else { $data = wp_get_attachment_metadata( $attachment_id ); $height = isset( $data['height'] ) ? $data['height'] : 0; @@ -1223,7 +1223,7 @@ endif; $parent_url = wp_get_attachment_url( $parent->ID ); $url = str_replace( wp_basename( $parent_url ), wp_basename( $cropped ), $parent_url ); - $size = @getimagesize( $cropped ); + $size = wp_getimagesize( $cropped ); $image_type = ( $size ) ? $size['mime'] : 'image/jpeg'; $object = array( diff --git a/wp-admin/includes/class-wp-site-icon.php b/wp-admin/includes/class-wp-site-icon.php index b97e8cd527..9aff0f2a8d 100644 --- a/wp-admin/includes/class-wp-site-icon.php +++ b/wp-admin/includes/class-wp-site-icon.php @@ -87,7 +87,7 @@ class WP_Site_Icon { $parent_url = wp_get_attachment_url( $parent->ID ); $url = str_replace( wp_basename( $parent_url ), wp_basename( $cropped ), $parent_url ); - $size = @getimagesize( $cropped ); + $size = wp_getimagesize( $cropped ); $image_type = ( $size ) ? $size['mime'] : 'image/jpeg'; $object = array( diff --git a/wp-admin/includes/image.php b/wp-admin/includes/image.php index 5e418a898b..e64c49c4d1 100644 --- a/wp-admin/includes/image.php +++ b/wp-admin/includes/image.php @@ -93,7 +93,7 @@ function wp_get_missing_image_subsizes( $attachment_id ) { // Use the originally uploaded image dimensions as full_width and full_height. if ( ! empty( $image_meta['original_image'] ) ) { $image_file = wp_get_original_image_path( $attachment_id ); - $imagesize = @getimagesize( $image_file ); + $imagesize = wp_getimagesize( $image_file ); } if ( ! empty( $imagesize ) ) { @@ -224,7 +224,7 @@ function _wp_image_meta_replace_original( $saved_data, $original_file, $image_me * @return array The image attachment meta data. */ function wp_create_image_subsizes( $file, $attachment_id ) { - $imagesize = @getimagesize( $file ); + $imagesize = wp_getimagesize( $file ); if ( empty( $imagesize ) ) { // File is not an image. @@ -687,7 +687,7 @@ function wp_read_image_metadata( $file ) { return false; } - list( , , $image_type ) = @getimagesize( $file ); + list( , , $image_type ) = wp_getimagesize( $file ); /* * EXIF contains a bunch of data we'll probably never need formatted in ways @@ -716,10 +716,21 @@ function wp_read_image_metadata( $file ) { * as caption, description etc. */ if ( is_callable( 'iptcparse' ) ) { - @getimagesize( $file, $info ); + wp_getimagesize( $file, $info ); if ( ! empty( $info['APP13'] ) ) { - $iptc = @iptcparse( $info['APP13'] ); + if ( + // Skip when running unit tests. + ! defined( 'DIR_TESTDATA' ) + && + // Process without silencing errors when in debug mode. + defined( 'WP_DEBUG' ) && WP_DEBUG + ) { + $iptc = iptcparse( $info['APP13'] ); + } else { + // phpcs:ignore WordPress.PHP.NoSilencedErrors -- Silencing notice and warning is intentional. See https://core.trac.wordpress.org/ticket/42480 + $iptc = @iptcparse( $info['APP13'] ); + } // Headline, "A brief synopsis of the caption". if ( ! empty( $iptc['2#105'][0] ) ) { @@ -779,7 +790,18 @@ function wp_read_image_metadata( $file ) { $exif_image_types = apply_filters( 'wp_read_image_metadata_types', array( IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM ) ); if ( is_callable( 'exif_read_data' ) && in_array( $image_type, $exif_image_types, true ) ) { - $exif = @exif_read_data( $file ); + if ( + // Skip when running unit tests. + ! defined( 'DIR_TESTDATA' ) + && + // Process without silencing errors when in debug mode. + defined( 'WP_DEBUG' ) && WP_DEBUG + ) { + $exif = exif_read_data( $file ); + } else { + // phpcs:ignore WordPress.PHP.NoSilencedErrors -- Silencing notice and warning is intentional. See https://core.trac.wordpress.org/ticket/42480 + $exif = @exif_read_data( $file ); + } if ( ! empty( $exif['ImageDescription'] ) ) { mbstring_binary_safe_encoding(); @@ -877,7 +899,7 @@ function wp_read_image_metadata( $file ) { * @return bool True if valid image, false if not valid image. */ function file_is_valid_image( $path ) { - $size = @getimagesize( $path ); + $size = wp_getimagesize( $path ); return ! empty( $size ); } @@ -892,7 +914,7 @@ function file_is_valid_image( $path ) { function file_is_displayable_image( $path ) { $displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_ICO ); - $info = @getimagesize( $path ); + $info = wp_getimagesize( $path ); if ( empty( $info ) ) { $result = false; } elseif ( ! in_array( $info[2], $displayable_image_types, true ) ) { diff --git a/wp-includes/class-wp-image-editor-gd.php b/wp-includes/class-wp-image-editor-gd.php index 3e3915368c..ed0a7be279 100644 --- a/wp-includes/class-wp-image-editor-gd.php +++ b/wp-includes/class-wp-image-editor-gd.php @@ -105,7 +105,7 @@ class WP_Image_Editor_GD extends WP_Image_Editor { return new WP_Error( 'invalid_image', __( 'File is not an image.' ), $this->file ); } - $size = @getimagesize( $this->file ); + $size = wp_getimagesize( $this->file ); if ( ! $size ) { return new WP_Error( 'invalid_image', __( 'Could not read image size.' ), $this->file ); diff --git a/wp-includes/deprecated.php b/wp-includes/deprecated.php index 90a2696c25..72a23cd836 100644 --- a/wp-includes/deprecated.php +++ b/wp-includes/deprecated.php @@ -1948,7 +1948,7 @@ function get_attachment_icon( $id = 0, $fullsize = false, $max_dims = false ) { // Do we need to constrain the image? if ( ($max_dims = apply_filters('attachment_max_dims', $max_dims)) && file_exists($src_file) ) { - $imagesize = @getimagesize($src_file); + $imagesize = wp_getimagesize($src_file); if (($imagesize[0] > $max_dims[0]) || $imagesize[1] > $max_dims[1] ) { $actual_aspect = $imagesize[0] / $imagesize[1]; diff --git a/wp-includes/functions.php b/wp-includes/functions.php index e6c218d8ad..a8c4747c39 100644 --- a/wp-includes/functions.php +++ b/wp-includes/functions.php @@ -3052,7 +3052,7 @@ function wp_get_image_mime( $file ) { $imagetype = exif_imagetype( $file ); $mime = ( $imagetype ) ? image_type_to_mime_type( $imagetype ) : false; } elseif ( function_exists( 'getimagesize' ) ) { - $imagesize = @getimagesize( $file ); + $imagesize = wp_getimagesize( $file ); $mime = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false; } else { $mime = false; @@ -7866,3 +7866,36 @@ function is_php_version_compatible( $required ) { function wp_fuzzy_number_match( $expected, $actual, $precision = 1 ) { return abs( (float) $expected - (float) $actual ) <= $precision; } + +/** + * Allows PHP's getimagesize() to be debuggable when necessary. + * + * @since 5.7.0 + * + * @param string $filename The file path. + * @param array $imageinfo Extended image information, passed by reference. + * @return array|false Array of image information or false on failure. + */ +function wp_getimagesize( $filename, &$imageinfo = array() ) { + if ( + // Skip when running unit tests. + ! defined( 'DIR_TESTDATA' ) + && + // Return without silencing errors when in debug mode. + defined( 'WP_DEBUG' ) && WP_DEBUG + ) { + return getimagesize( $filename, $imageinfo ); + } + + /** + * Silencing notice and warning is intentional. + * + * getimagesize() has a tendency to generate errors, such as "corrupt JPEG data: 7191 extraneous bytes before + * marker", even when it's able to provide image size information. + * + * See https://core.trac.wordpress.org/ticket/42480 + * + * phpcs:ignore WordPress.PHP.NoSilencedErrors + */ + return @getimagesize( $filename, $imageinfo ); +} diff --git a/wp-includes/media.php b/wp-includes/media.php index ea8ca0b68c..cf3a9d9f31 100644 --- a/wp-includes/media.php +++ b/wp-includes/media.php @@ -244,7 +244,7 @@ function image_downsize( $id, $size = 'medium' ) { $info = null; if ( $thumb_file ) { - $info = @getimagesize( $thumb_file ); + $info = wp_getimagesize( $thumb_file ); } if ( $thumb_file && $info ) { @@ -962,7 +962,7 @@ function wp_get_attachment_image_src( $attachment_id, $size = 'thumbnail', $icon $icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/media' ); $src_file = $icon_dir . '/' . wp_basename( $src ); - list( $width, $height ) = @getimagesize( $src_file ); + list( $width, $height ) = wp_getimagesize( $src_file ); } } diff --git a/wp-includes/version.php b/wp-includes/version.php index 23a5e70ad7..a7a1148da5 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -13,7 +13,7 @@ * * @global string $wp_version */ -$wp_version = '5.7-alpha-50145'; +$wp_version = '5.7-alpha-50146'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.