diff -r be944660c56a -r 3d72ae0968f4 wp/wp-admin/includes/image.php --- 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 ) ) {