@@ -3101,7 +3101,13 @@ function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
31013101 // Attempt to figure out what type of image it actually is.
31023102 $ real_mime = wp_get_image_mime ( $ file );
31033103
3104- if ( $ real_mime && $ real_mime !== $ type ) {
3104+ $ heic_images_etx = array (
3105+ 'heif ' ,
3106+ 'heics ' ,
3107+ 'heifs ' ,
3108+ );
3109+
3110+ if ( $ real_mime && ( $ real_mime !== $ type || in_array ( $ ext , $ heic_images_etx , true ) ) ) {
31053111 /**
31063112 * Filters the list mapping image mime types to their respective extensions.
31073113 *
@@ -3119,13 +3125,24 @@ function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
31193125 'image/tiff ' => 'tif ' ,
31203126 'image/webp ' => 'webp ' ,
31213127 'image/avif ' => 'avif ' ,
3128+
3129+ /*
3130+ * In theory there are/should be file extensions that correspond to the
3131+ * mime types: .heif, .heics and .heifs. However it seems that HEIC images
3132+ * with any of the mime types commonly have a .heic file extension.
3133+ * Seems keeping the status quo here is best for compatibility.
3134+ */
31223135 'image/heic ' => 'heic ' ,
3136+ 'image/heif ' => 'heic ' ,
3137+ 'image/heic-sequence ' => 'heic ' ,
3138+ 'image/heif-sequence ' => 'heic ' ,
31233139 )
31243140 );
31253141
31263142 // Replace whatever is after the last period in the filename with the correct extension.
31273143 if ( ! empty ( $ mime_to_ext [ $ real_mime ] ) ) {
31283144 $ filename_parts = explode ( '. ' , $ filename );
3145+
31293146 array_pop ( $ filename_parts );
31303147 $ filename_parts [] = $ mime_to_ext [ $ real_mime ];
31313148 $ new_filename = implode ( '. ' , $ filename_parts );
@@ -3316,9 +3333,7 @@ function wp_get_image_mime( $file ) {
33163333 $ mime = ( $ imagetype ) ? image_type_to_mime_type ( $ imagetype ) : false ;
33173334 } elseif ( function_exists ( 'getimagesize ' ) ) {
33183335 // Don't silence errors when in debug mode, unless running unit tests.
3319- if ( defined ( 'WP_DEBUG ' ) && WP_DEBUG
3320- && ! defined ( 'WP_RUN_CORE_TESTS ' )
3321- ) {
3336+ if ( defined ( 'WP_DEBUG ' ) && WP_DEBUG && ! defined ( 'WP_RUN_CORE_TESTS ' ) ) {
33223337 // Not using wp_getimagesize() here to avoid an infinite loop.
33233338 $ imagesize = getimagesize ( $ file );
33243339 } else {
@@ -3365,22 +3380,28 @@ function wp_get_image_mime( $file ) {
33653380 // Divide the header string into 4 byte groups.
33663381 $ magic = str_split ( $ magic , 8 );
33673382
3368- if (
3369- isset ( $ magic [1 ] ) &&
3370- isset ( $ magic [2 ] ) &&
3371- 'ftyp ' === hex2bin ( $ magic [1 ] ) &&
3372- ( 'avif ' === hex2bin ( $ magic [2 ] ) || 'avis ' === hex2bin ( $ magic [2 ] ) )
3373- ) {
3374- $ mime = 'image/avif ' ;
3375- }
3383+ if ( isset ( $ magic [1 ] ) && isset ( $ magic [2 ] ) && 'ftyp ' === hex2bin ( $ magic [1 ] ) ) {
3384+ if ( 'avif ' === hex2bin ( $ magic [2 ] ) || 'avis ' === hex2bin ( $ magic [2 ] ) ) {
3385+ $ mime = 'image/avif ' ;
3386+ } elseif ( 'heic ' === hex2bin ( $ magic [2 ] ) ) {
3387+ $ mime = 'image/heic ' ;
3388+ } elseif ( 'heif ' === hex2bin ( $ magic [2 ] ) ) {
3389+ $ mime = 'image/heif ' ;
3390+ } else {
3391+ /*
3392+ * HEIC/HEIF images and image sequences/animations may have other strings here
3393+ * like mif1, msf1, etc. For now fall back to using finfo_file() to detect these.
3394+ */
3395+ if ( extension_loaded ( 'fileinfo ' ) ) {
3396+ $ fileinfo = finfo_open ( FILEINFO_MIME_TYPE );
3397+ $ mime_type = finfo_file ( $ fileinfo , $ file );
3398+ finfo_close ( $ fileinfo );
33763399
3377- if (
3378- isset ( $ magic [1 ] ) &&
3379- isset ( $ magic [2 ] ) &&
3380- 'ftyp ' === hex2bin ( $ magic [1 ] ) &&
3381- ( 'heic ' === hex2bin ( $ magic [2 ] ) || 'heif ' === hex2bin ( $ magic [2 ] ) )
3382- ) {
3383- $ mime = 'image/heic ' ;
3400+ if ( wp_is_heic_image_mime_type ( $ mime_type ) ) {
3401+ $ mime = $ mime_type ;
3402+ }
3403+ }
3404+ }
33843405 }
33853406 } catch ( Exception $ e ) {
33863407 $ mime = false ;
@@ -3423,7 +3444,13 @@ function wp_get_mime_types() {
34233444 'webp ' => 'image/webp ' ,
34243445 'avif ' => 'image/avif ' ,
34253446 'ico ' => 'image/x-icon ' ,
3447+
3448+ // TODO: Needs improvement. All images with the following mime types seem to have .heic file extension.
34263449 'heic ' => 'image/heic ' ,
3450+ 'heif ' => 'image/heif ' ,
3451+ 'heics ' => 'image/heic-sequence ' ,
3452+ 'heifs ' => 'image/heif-sequence ' ,
3453+
34273454 // Video formats.
34283455 'asf|asx ' => 'video/x-ms-asf ' ,
34293456 'wmv ' => 'video/x-ms-wmv ' ,
@@ -3543,7 +3570,7 @@ function wp_get_ext_types() {
35433570 return apply_filters (
35443571 'ext2type ' ,
35453572 array (
3546- 'image ' => array ( 'jpg ' , 'jpeg ' , 'jpe ' , 'gif ' , 'png ' , 'bmp ' , 'tif ' , 'tiff ' , 'ico ' , 'heic ' , 'webp ' , 'avif ' ),
3573+ 'image ' => array ( 'jpg ' , 'jpeg ' , 'jpe ' , 'gif ' , 'png ' , 'bmp ' , 'tif ' , 'tiff ' , 'ico ' , 'heic ' , 'heif ' , ' webp ' , 'avif ' ),
35473574 'audio ' => array ( 'aac ' , 'ac3 ' , 'aif ' , 'aiff ' , 'flac ' , 'm3a ' , 'm4a ' , 'm4b ' , 'mka ' , 'mp1 ' , 'mp2 ' , 'mp3 ' , 'ogg ' , 'oga ' , 'ram ' , 'wav ' , 'wma ' ),
35483575 'video ' => array ( '3g2 ' , '3gp ' , '3gpp ' , 'asf ' , 'avi ' , 'divx ' , 'dv ' , 'flv ' , 'm4v ' , 'mkv ' , 'mov ' , 'mp4 ' , 'mpeg ' , 'mpg ' , 'mpv ' , 'ogm ' , 'ogv ' , 'qt ' , 'rm ' , 'vob ' , 'wmv ' ),
35493576 'document ' => array ( 'doc ' , 'docx ' , 'docm ' , 'dotm ' , 'odt ' , 'pages ' , 'pdf ' , 'xps ' , 'oxps ' , 'rtf ' , 'wp ' , 'wpd ' , 'psd ' , 'xcf ' ),
@@ -9037,3 +9064,22 @@ function wp_admin_notice( $message, $args = array() ) {
90379064
90389065 echo wp_kses_post ( wp_get_admin_notice ( $ message , $ args ) );
90399066}
9067+
9068+ /**
9069+ * Checks if a mime type is for a HEIC/HEIF image.
9070+ *
9071+ * @since 6.7.0
9072+ *
9073+ * @param string $mime_type The mime type to check.
9074+ * @return bool Whether the mime type is for a HEIC/HEIF image.
9075+ */
9076+ function wp_is_heic_image_mime_type ( $ mime_type ) {
9077+ $ heic_mime_types = array (
9078+ 'image/heic ' ,
9079+ 'image/heif ' ,
9080+ 'image/heic-sequence ' ,
9081+ 'image/heif-sequence ' ,
9082+ );
9083+
9084+ return in_array ( $ mime_type , $ heic_mime_types , true );
9085+ }
0 commit comments