WordPress 4.6.2
[autoinstalls/wordpress.git] / wp-includes / functions.php
index ff09f3459d3bdf150462f8194727046ace99bee7..e3c9294909dced48a27dda773e5ef4af0af15966 100644 (file)
@@ -2234,7 +2234,7 @@ function wp_check_filetype( $filename, $mimes = null ) {
  * If it's determined that the extension does not match the file's real type,
  * then the "proper_filename" value will be set with a proper filename and extension.
  *
- * Currently this function only supports validating images known to getimagesize().
+ * Currently this function only supports renaming images validated via wp_get_image_mime().
  *
  * @since 3.0.0
  *
@@ -2258,14 +2258,15 @@ function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
                return compact( 'ext', 'type', 'proper_filename' );
        }
 
-       // We're able to validate images using GD
-       if ( $type && 0 === strpos( $type, 'image/' ) && function_exists('getimagesize') ) {
+       // Validate image types.
+       if ( $type && 0 === strpos( $type, 'image/' ) ) {
 
                // Attempt to figure out what type of image it actually is
-               $imgstats = @getimagesize( $file );
+               $real_mime = wp_get_image_mime( $file );
 
-               // If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME
-               if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {
+               if ( ! $real_mime ) {
+                       $type = $ext = false;
+               } elseif ( $real_mime != $type ) {
                        /**
                         * Filters the list mapping image mime types to their respective extensions.
                         *
@@ -2282,10 +2283,10 @@ function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
                        ) );
 
                        // Replace whatever is after the last period in the filename with the correct extension
-                       if ( ! empty( $mime_to_ext[ $imgstats['mime'] ] ) ) {
+                       if ( ! empty( $mime_to_ext[ $real_mime ] ) ) {
                                $filename_parts = explode( '.', $filename );
                                array_pop( $filename_parts );
-                               $filename_parts[] = $mime_to_ext[ $imgstats['mime'] ];
+                               $filename_parts[] = $mime_to_ext[ $real_mime ];
                                $new_filename = implode( '.', $filename_parts );
 
                                if ( $new_filename != $filename ) {
@@ -2295,8 +2296,20 @@ function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
                                $wp_filetype = wp_check_filetype( $new_filename, $mimes );
                                $ext = $wp_filetype['ext'];
                                $type = $wp_filetype['type'];
+                       } else {
+                               $type = $ext = false;
                        }
                }
+       } elseif ( function_exists( 'finfo_file' ) ) {
+               // Use finfo_file if available to validate non-image files.
+               $finfo = finfo_open( FILEINFO_MIME_TYPE );
+               $real_mime = finfo_file( $finfo, $file );
+               finfo_close( $finfo );
+
+               // If the extension does not match the file's real type, return false.
+               if ( $real_mime !== $type ) {
+                       $type = $ext = false;
+               }
        }
 
        /**
@@ -2314,6 +2327,38 @@ function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
        return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
 }
 
+/**
+ * Returns the real mime type of an image file.
+ *
+ * This depends on exif_imagetype() or getimagesize() to determine real mime types.
+ *
+ * @since 4.7.1
+ *
+ * @param string $file Full path to the file.
+ * @return string|false The actual mime type or false if the type cannot be determined.
+ */
+function wp_get_image_mime( $file ) {
+       /*
+        * Use exif_imagetype() to check the mimetype if available or fall back to
+        * getimagesize() if exif isn't avaialbe. If either function throws an Exception
+        * we assume the file could not be validated.
+        */
+       try {
+               if ( is_callable( 'exif_imagetype' ) ) {
+                       $mime = image_type_to_mime_type( exif_imagetype( $file ) );
+               } elseif ( function_exists( 'getimagesize' ) ) {
+                       $imagesize = getimagesize( $file );
+                       $mime = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false;
+               } else {
+                       $mime = false;
+               }
+       } catch ( Exception $e ) {
+               $mime = false;
+       }
+
+       return $mime;
+}
+
 /**
  * Retrieve list of mime types and file extensions.
  *