wp/wp-admin/includes/image.php
changeset 19 3d72ae0968f4
parent 18 be944660c56a
child 21 48c4eec2b7e6
--- a/wp/wp-admin/includes/image.php	Wed Sep 21 18:19:35 2022 +0200
+++ b/wp/wp-admin/includes/image.php	Tue Sep 27 16:37:53 2022 +0200
@@ -63,6 +63,10 @@
 		return $result;
 	}
 
+	if ( ! empty( $result['path'] ) ) {
+		return $result['path'];
+	}
+
 	return $dst_file;
 }
 
@@ -75,7 +79,8 @@
  * @since 5.3.0
  *
  * @param int $attachment_id The image attachment post ID.
- * @return array An array of the image sub-sizes that are currently defined but don't exist for this image.
+ * @return array[] Associative array of arrays of image sub-size information for
+ *                 missing image sizes, keyed by image size name.
  */
 function wp_get_missing_image_subsizes( $attachment_id ) {
 	if ( ! wp_attachment_is_image( $attachment_id ) ) {
@@ -131,9 +136,10 @@
 	 *
 	 * @since 5.3.0
 	 *
-	 * @param array $missing_sizes Array with the missing image sub-sizes.
-	 * @param array $image_meta    The image meta data.
-	 * @param int   $attachment_id The image attachment post ID.
+	 * @param array[] $missing_sizes Associative array of arrays of image sub-size information for
+	 *                               missing image sizes, keyed by image size name.
+	 * @param array   $image_meta    The image meta data.
+	 * @param int     $attachment_id The image attachment post ID.
 	 */
 	return apply_filters( 'wp_get_missing_image_subsizes', $missing_sizes, $image_meta, $attachment_id );
 }
@@ -208,6 +214,9 @@
 	// Store the original image file name in image_meta.
 	$image_meta['original_image'] = wp_basename( $original_file );
 
+	// Add image file size.
+	$image_meta['filesize'] = wp_filesize( $new_file );
+
 	return $image_meta;
 }
 
@@ -220,7 +229,7 @@
  * @since 5.3.0
  *
  * @param string $file          Full path to the image file.
- * @param int    $attachment_id Attachment Id to process.
+ * @param int    $attachment_id Attachment ID to process.
  * @return array The image attachment meta data.
  */
 function wp_create_image_subsizes( $file, $attachment_id ) {
@@ -233,10 +242,11 @@
 
 	// Default image meta.
 	$image_meta = array(
-		'width'  => $imagesize[0],
-		'height' => $imagesize[1],
-		'file'   => _wp_relative_upload_path( $file ),
-		'sizes'  => array(),
+		'width'    => $imagesize[0],
+		'height'   => $imagesize[1],
+		'file'     => _wp_relative_upload_path( $file ),
+		'filesize' => wp_filesize( $file ),
+		'sizes'    => array(),
 	);
 
 	// Fetch additional metadata from EXIF/IPTC.
@@ -378,7 +388,7 @@
  * @param array  $new_sizes     Array defining what sizes to create.
  * @param string $file          Full path to the image file.
  * @param array  $image_meta    The attachment meta data array.
- * @param int    $attachment_id Attachment Id to process.
+ * @param int    $attachment_id Attachment ID to process.
  * @return array The attachment meta data with updated `sizes` array. Includes an array of errors encountered while resizing.
  */
 function _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id ) {
@@ -468,8 +478,8 @@
  *
  * @since 2.1.0
  *
- * @param int    $attachment_id Attachment Id to process.
- * @param string $file          Filepath of the Attached image.
+ * @param int    $attachment_id Attachment ID to process.
+ * @param string $file          Filepath of the attached image.
  * @return array Metadata for attachment.
  */
 function wp_generate_attachment_metadata( $attachment_id, $file ) {
@@ -627,6 +637,11 @@
 	// Remove the blob of binary data from the array.
 	unset( $metadata['image']['data'] );
 
+	// Capture file size for cases where it has not been captured yet, such as PDFs.
+	if ( ! isset( $metadata['filesize'] ) && file_exists( $file ) ) {
+		$metadata['filesize'] = wp_filesize( $file );
+	}
+
 	/**
 	 * Filters the generated attachment meta data.
 	 *
@@ -646,19 +661,40 @@
  *
  * @since 2.5.0
  *
- * @param string $str
- * @return int|float
+ * @param string $str Fraction string.
+ * @return int|float Returns calculated fraction or integer 0 on invalid input.
  */
 function wp_exif_frac2dec( $str ) {
-	if ( false === strpos( $str, '/' ) ) {
-		return $str;
+	if ( ! is_scalar( $str ) || is_bool( $str ) ) {
+		return 0;
+	}
+
+	if ( ! is_string( $str ) ) {
+		return $str; // This can only be an integer or float, so this is fine.
+	}
+
+	// Fractions passed as a string must contain a single `/`.
+	if ( substr_count( $str, '/' ) !== 1 ) {
+		if ( is_numeric( $str ) ) {
+			return (float) $str;
+		}
+
+		return 0;
 	}
 
 	list( $numerator, $denominator ) = explode( '/', $str );
-	if ( ! empty( $denominator ) ) {
-		return $numerator / $denominator;
+
+	// Both the numerator and the denominator must be numbers.
+	if ( ! is_numeric( $numerator ) || ! is_numeric( $denominator ) ) {
+		return 0;
 	}
-	return $str;
+
+	// The denominator must not be zero.
+	if ( 0 == $denominator ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison -- Deliberate loose comparison.
+		return 0;
+	}
+
+	return $numerator / $denominator;
 }
 
 /**
@@ -666,8 +702,8 @@
  *
  * @since 2.5.0
  *
- * @param string $str
- * @return int
+ * @param string $str A date string expected to be in Exif format (Y:m:d H:i:s).
+ * @return int|false The unix timestamp, or false on failure.
  */
 function wp_exif_date2ts( $str ) {
 	list( $date, $time ) = explode( ' ', trim( $str ) );
@@ -740,6 +776,10 @@
 				$iptc = @iptcparse( $info['APP13'] );
 			}
 
+			if ( ! is_array( $iptc ) ) {
+				$iptc = array();
+			}
+
 			// Headline, "A brief synopsis of the caption".
 			if ( ! empty( $iptc['2#105'][0] ) ) {
 				$meta['title'] = trim( $iptc['2#105'][0] );
@@ -793,7 +833,8 @@
 	 *
 	 * @since 2.5.0
 	 *
-	 * @param array $image_types Image types to check for exif data.
+	 * @param int[] $image_types Array of image types to check for exif data. Each value
+	 *                           is usually one of the `IMAGETYPE_*` constants.
 	 */
 	$exif_image_types = apply_filters( 'wp_read_image_metadata_types', array( IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM ) );
 
@@ -808,6 +849,10 @@
 			$exif = @exif_read_data( $file );
 		}
 
+		if ( ! is_array( $exif ) ) {
+			$exif = array();
+		}
+
 		if ( ! empty( $exif['ImageDescription'] ) ) {
 			mbstring_binary_safe_encoding();
 			$description_length = strlen( $exif['ImageDescription'] );
@@ -840,7 +885,7 @@
 		if ( empty( $meta['copyright'] ) && ! empty( $exif['Copyright'] ) ) {
 			$meta['copyright'] = trim( $exif['Copyright'] );
 		}
-		if ( ! empty( $exif['FNumber'] ) ) {
+		if ( ! empty( $exif['FNumber'] ) && is_scalar( $exif['FNumber'] ) ) {
 			$meta['aperture'] = round( wp_exif_frac2dec( $exif['FNumber'] ), 2 );
 		}
 		if ( ! empty( $exif['Model'] ) ) {
@@ -850,14 +895,20 @@
 			$meta['created_timestamp'] = wp_exif_date2ts( $exif['DateTimeDigitized'] );
 		}
 		if ( ! empty( $exif['FocalLength'] ) ) {
-			$meta['focal_length'] = (string) wp_exif_frac2dec( $exif['FocalLength'] );
+			$meta['focal_length'] = (string) $exif['FocalLength'];
+			if ( is_scalar( $exif['FocalLength'] ) ) {
+				$meta['focal_length'] = (string) wp_exif_frac2dec( $exif['FocalLength'] );
+			}
 		}
 		if ( ! empty( $exif['ISOSpeedRatings'] ) ) {
 			$meta['iso'] = is_array( $exif['ISOSpeedRatings'] ) ? reset( $exif['ISOSpeedRatings'] ) : $exif['ISOSpeedRatings'];
 			$meta['iso'] = trim( $meta['iso'] );
 		}
 		if ( ! empty( $exif['ExposureTime'] ) ) {
-			$meta['shutter_speed'] = (string) wp_exif_frac2dec( $exif['ExposureTime'] );
+			$meta['shutter_speed'] = (string) $exif['ExposureTime'];
+			if ( is_scalar( $exif['ExposureTime'] ) ) {
+				$meta['shutter_speed'] = (string) wp_exif_frac2dec( $exif['ExposureTime'] );
+			}
 		}
 		if ( ! empty( $exif['Orientation'] ) ) {
 			$meta['orientation'] = $exif['Orientation'];
@@ -917,7 +968,7 @@
  * @return bool True if suitable, false if not suitable.
  */
 function file_is_displayable_image( $path ) {
-	$displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_ICO, IMAGETYPE_WEBP ); // phpcs:ignore PHPCompatibility.Constants.NewConstants.imagetype_webpFound
+	$displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_ICO, IMAGETYPE_WEBP );
 
 	$info = wp_getimagesize( $path );
 	if ( empty( $info ) ) {