Make WordPress Core

Changeset 39842 for branches/3.7/src


Ignore:
Timestamp:
01/11/2017 01:21:01 PM (8 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.

Merges [39831] to the 3.7 branch.

Location:
branches/3.7
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/3.7

  • branches/3.7/src

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

    r27887 r39842  
    18791879 * then the "proper_filename" value will be set with a proper filename and extension.
    18801880 *
    1881  * Currently this function only supports validating images known to getimagesize().
     1881 * Currently this function only supports renaming images validated via wp_get_image_mime().
    18821882 *
    18831883 * @since 3.0.0
     
    19001900        return compact( 'ext', 'type', 'proper_filename' );
    19011901
    1902     // We're able to validate images using GD
    1903     if ( $type && 0 === strpos( $type, 'image/' ) && function_exists('getimagesize') ) {
     1902    // Validate image types.
     1903    if ( $type && 0 === strpos( $type, 'image/' ) ) {
    19041904
    19051905        // Attempt to figure out what type of image it actually is
    1906         $imgstats = @getimagesize( $file );
    1907 
    1908         // If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME
    1909         if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {
     1906        $real_mime = wp_get_image_mime( $file );
     1907
     1908        if ( ! $real_mime ) {
     1909            $type = $ext = false;
     1910        } elseif ( $real_mime != $type ) {
    19101911            // This is a simplified array of MIMEs that getimagesize() can detect and their extensions
    19111912            // You shouldn't need to use this filter, but it's here just in case
     
    19191920
    19201921            // Replace whatever is after the last period in the filename with the correct extension
    1921             if ( ! empty( $mime_to_ext[ $imgstats['mime'] ] ) ) {
     1922            if ( ! empty( $mime_to_ext[ $real_mime ] ) ) {
    19221923                $filename_parts = explode( '.', $filename );
    19231924                array_pop( $filename_parts );
    1924                 $filename_parts[] = $mime_to_ext[ $imgstats['mime'] ];
     1925                $filename_parts[] = $mime_to_ext[ $real_mime ];
    19251926                $new_filename = implode( '.', $filename_parts );
    19261927
     
    19311932                $wp_filetype = wp_check_filetype( $new_filename, $mimes );
    19321933                extract( $wp_filetype );
     1934            } else {
     1935                $type = $ext = false;
    19331936            }
     1937        }
     1938    } elseif ( function_exists( 'finfo_file' ) ) {
     1939        // Use finfo_file if available to validate non-image files.
     1940        $finfo = finfo_open( FILEINFO_MIME_TYPE );
     1941        $real_mime = finfo_file( $finfo, $file );
     1942        finfo_close( $finfo );
     1943
     1944        // If the extension does not match the file's real type, return false.
     1945        if ( $real_mime !== $type ) {
     1946            $type = $ext = false;
    19341947        }
    19351948    }
     
    19381951    // Should return an array in the style of array( 'ext' => $ext, 'type' => $type, 'proper_filename' => $proper_filename )
    19391952    return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
     1953}
     1954
     1955/**
     1956 * Returns the real mime type of an image file.
     1957 *
     1958 * This depends on exif_imagetype() or getimagesize() to determine real mime types.
     1959 *
     1960 * @since 4.7.1
     1961 *
     1962 * @param string $file Full path to the file.
     1963 * @return string|false The actual mime type or false if the type cannot be determined.
     1964 */
     1965function wp_get_image_mime( $file ) {
     1966    /*
     1967     * Use exif_imagetype() to check the mimetype if available or fall back to
     1968     * getimagesize() if exif isn't avaialbe. If either function throws an Exception
     1969     * we assume the file could not be validated.
     1970     */
     1971    try {
     1972        if ( ! is_callable( 'exif_imagetype' ) ) {
     1973            $mime = image_type_to_mime_type( exif_imagetype( $file ) );
     1974        } elseif ( function_exists( 'getimagesize' ) ) {
     1975            $imagesize = getimagesize( $file );
     1976            $mime = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false;
     1977        } else {
     1978            $mime = false;
     1979        }
     1980    } catch ( Exception $e ) {
     1981        $mime = false;
     1982    }
     1983
     1984    return $mime;
    19401985}
    19411986
Note: See TracChangeset for help on using the changeset viewer.