WordPress.org

Make WordPress Core

Changeset 39832


Ignore:
Timestamp:
01/11/17 13:11:52 (9 months 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.

Merges [39831] to the 4.7 branch.

Location:
branches/4.7
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/4.7

  • branches/4.7/src/wp-includes/functions.php

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