Make WordPress Core

Changeset 39831


Ignore:
Timestamp:
01/11/2017 01:07:54 PM (10 years ago)
Author:
joemcgill
Message:

Media: Improve image filetype checking.

This adds a new function wp_get_image_mime() which is used by
wp_check_filetype_and_ext() to validate image files using
exif_imagetype() if available instead of getimagesize().

getimagesize() is less performant than exif_imagetype() and is
dependent on GD. If exif_imagetype() is not available, it falls back to
getimagesize() as before.

If wp_check_filetype_and_ext() can't validate the filetype, we now return
false for ext/MIME values.

See #11946.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/functions.php

    r39639 r39831  
    22562256 * then the "proper_filename" value will be set with a proper filename and extension.
    22572257 *
    2258  * Currently this function only supports validating images known to getimagesize().
     2258 * Currently this function only supports renaming images validated via wp_get_image_mime().
    22592259 *
    22602260 * @since 3.0.0
    … …  
    22802280        }
    22812281
    2282         // We're able to validate images using GD
    2283         if ( $type && 0 === strpos( $type, 'image/' ) && function_exists('getimagesize') ) {
     2282        // Validate image types.
     2283        if ( $type && 0 === strpos( $type, 'image/' ) ) {
    22842284
    22852285                // Attempt to figure out what type of image it actually is
    2286                 $imgstats = @getimagesize( $file );
    2287 
    2288                 // If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME
    2289                 if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {
     2286                $real_mime = wp_get_image_mime( $file );
     2287
     2288                if ( ! $real_mime ) {
     2289                        $type = $ext = false;
     2290                } elseif ( $real_mime != $type ) {
    22902291                        /**
    22912292                         * Filters the list mapping image mime types to their respective extensions.
    … …  
    23042305
    23052306                        // Replace whatever is after the last period in the filename with the correct extension
    2306                         if ( ! empty( $mime_to_ext[ $imgstats['mime'] ] ) ) {
     2307                        if ( ! empty( $mime_to_ext[ $real_mime ] ) ) {
    23072308                                $filename_parts = explode( '.', $filename );
    23082309                                array_pop( $filename_parts );
    2309                                 $filename_parts[] = $mime_to_ext[ $imgstats['mime'] ];
     2310                                $filename_parts[] = $mime_to_ext[ $real_mime ];
    23102311                                $new_filename = implode( '.', $filename_parts );
    23112312
    … …  
    23172318                                $ext = $wp_filetype['ext'];
    23182319                                $type = $wp_filetype['type'];
     2320                        } else {
     2321                                $type = $ext = false;
    23192322                        }
     2323                }
     2324        } elseif ( function_exists( 'finfo_file' ) ) {
     2325                // Use finfo_file if available to validate non-image files.
     2326                $finfo = finfo_open( FILEINFO_MIME_TYPE );
     2327                $real_mime = finfo_file( $finfo, $file );
     2328                finfo_close( $finfo );
     2329
     2330                // If the extension does not match the file's real type, return false.
     2331                if ( $real_mime !== $type ) {
     2332                        $type = $ext = false;
    23202333                }
    23212334        }
    … …  
    23342347         */
    23352348        return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
     2349}
     2350
     2351/**
     2352 * Returns the real mime type of an image file.
     2353 *
     2354 * This depends on exif_imagetype() or getimagesize() to determine real mime types.
     2355 *
     2356 * @since 4.7.1
     2357 *
     2358 * @param string $file Full path to the file.
     2359 * @return string|false The actual mime type or false if the type cannot be determined.
     2360 */
     2361function wp_get_image_mime( $file ) {
     2362        /*
     2363         * Use exif_imagetype() to check the mimetype if available or fall back to
     2364         * getimagesize() if exif isn't avaialbe. If either function throws an Exception
     2365         * we assume the file could not be validated.
     2366         */
     2367        try {
     2368                if ( ! is_callable( 'exif_imagetype' ) ) {
     2369                        $mime = image_type_to_mime_type( exif_imagetype( $file ) );
     2370                } elseif ( function_exists( 'getimagesize' ) ) {
     2371                        $imagesize = getimagesize( $file );
     2372                        $mime = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false;
     2373                } else {
     2374                        $mime = false;
     2375                }
     2376        } catch ( Exception $e ) {
     2377                $mime = false;
     2378        }
     2379
     2380        return $mime;
    23362381}
    23372382
Note: See TracChangeset for help on using the changeset viewer.