WordPress.org

Make WordPress Core

Changeset 14649


Ignore:
Timestamp:
05/15/2010 04:47:03 AM (9 years ago)
Author:
nacin
Message:

Introduce wp_check_filetype_and_ext() to handle mime/ext image comparisons and corrections for upload and sideload. props Viper007Bond, see #11946.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/includes/file.php

    r14427 r14649  
    307307    // A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter.
    308308    if ( $test_type ) {
    309         $wp_filetype = wp_check_filetype( $file['name'], $mimes );
     309        $wp_filetype = wp_check_filetype_and_ext( $file['tmp_name'], $file['name'], $mimes );
    310310
    311311        extract( $wp_filetype );
     312
     313        // Check to see if wp_check_filetype_and_ext() determined the filename was incorrect
     314        if ( $proper_filename )
     315            $file['name'] = $proper_filename;
    312316
    313317        if ( ( !$type || !$ext ) && !current_user_can( 'unfiltered_upload' ) )
     
    417421    // A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter.
    418422    if ( $test_type ) {
    419         $wp_filetype = wp_check_filetype( $file['name'], $mimes );
     423        $wp_filetype = wp_check_filetype_and_ext( $file['tmp_name'], $file['name'], $mimes );
    420424
    421425        extract( $wp_filetype );
    422426
    423         // If the file claims to be an image, validate it's extension
    424         if ( function_exists('getimagesize') && !empty( $type ) && 'image/' == substr( $type, 0, 6 ) && is_uploaded_file( $file['tmp_name'] ) ) {
    425             // Attempt to figure out what type of image it really is
    426             $imgstats = @getimagesize( $file['tmp_name'] );
    427 
    428             // If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME
    429             if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {
    430                 // This is a simplified array of MIMEs that getimagesize() can detect and their extensions
    431                 $mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(
    432                     'image/jpeg' => 'jpg',
    433                     'image/png'  => 'png',
    434                     'image/gif'  => 'gif',
    435                     'image/bmp'  => 'bmp',
    436                     'image/tiff' => 'tif',
    437                 ) );
    438 
    439                 // Replace whatever's after the last period in the filename with the correct extension
    440                 if ( !empty($mime_to_ext[$imgstats['mime']]) ) {
    441                     $filename_parts = explode( '.', $file['name'] );
    442                     array_pop( $filename_parts );
    443                     $filename_parts[] = $mime_to_ext[$imgstats['mime']];
    444                     $file['name'] = implode( '.', $filename_parts );
    445 
    446                     // Re-validate the extension / MIME
    447                     $wp_filetype = wp_check_filetype( $file['name'], $mimes );
    448                     extract( $wp_filetype );
    449                 }
    450             }
    451         }
     427        // Check to see if wp_check_filetype_and_ext() determined the filename was incorrect
     428        if ( $proper_filename )
     429            $file['name'] = $proper_filename;
    452430
    453431        if ( ( !$type || !$ext ) && !current_user_can( 'unfiltered_upload' ) )
  • trunk/wp-includes/functions.php

    r14641 r14649  
    23612361
    23622362    return compact( 'ext', 'type' );
     2363}
     2364
     2365/**
     2366 * Attempt to determine the real file type of a file.
     2367 * If unable to, the file name extension will be used to determine type.
     2368 *
     2369 * If it's determined that the extension does not match the file's real type,
     2370 * then the "proper_filename" value will be set with a proper filename and extension.
     2371 *
     2372 * Currently this function only supports validating images known to getimagesize().
     2373 *
     2374 * @since 3.0.0
     2375 *
     2376 * @param string $file Full path to the image.
     2377 * @param string $filename The filename of the image (may differ from $file due to $file being in a tmp directory)
     2378 * @param array $mimes Optional. Key is the file extension with value as the mime type.
     2379 * @return array Values for the extension, MIME, and either a corrected filename or false if original $filename is valid
     2380 */
     2381function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
     2382
     2383    $proper_filename = false;
     2384
     2385    // Do basic extension validation and MIME mapping
     2386    $wp_filetype = wp_check_filetype( $filename, $mimes );
     2387    extract( $wp_filetype );
     2388
     2389    // We can't do any further validation without a file to work with
     2390    if ( ! file_exists( $file ) )
     2391        return compact( 'ext', 'type', 'proper_filename' );
     2392
     2393    // We're able to validate images using GD
     2394    if ( $type && 0 === strpos( $type, 'image/' ) && function_exists('getimagesize') ) {
     2395
     2396        // Attempt to figure out what type of image it actually is
     2397        $imgstats = @getimagesize( $file );
     2398
     2399        // If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME
     2400        if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {
     2401            // This is a simplified array of MIMEs that getimagesize() can detect and their extensions
     2402            // You shouldn't need to use this filter, but it's here just in case
     2403            $mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(
     2404                'image/jpeg' => 'jpg',
     2405                'image/png'  => 'png',
     2406                'image/gif'  => 'gif',
     2407                'image/bmp'  => 'bmp',
     2408                'image/tiff' => 'tif',
     2409            ) );
     2410
     2411            // Replace whatever is after the last period in the filename with the correct extension
     2412            if ( ! empty( $mime_to_ext[ $imgstats['mime'] ] ) ) {
     2413                $filename_parts = explode( '.', $filename );
     2414                array_pop( $filename_parts );
     2415                $filename_parts[] = $mime_to_ext[ $imgstats['mime'] ];
     2416                $new_filename = implode( '.', $filename_parts );
     2417
     2418                if ( $new_filename != $filename )
     2419                    $proper_filename = $new_filename; // Mark that it changed
     2420
     2421                // Redefine the extension / MIME
     2422                $wp_filetype = wp_check_filetype( $new_filename, $mimes );
     2423                extract( $wp_filetype );
     2424            }
     2425        }
     2426    }
     2427
     2428    // Let plugins try and validate other types of files
     2429    // Should return an array in the style of array( 'ext' => $ext, 'type' => $type, 'proper_filename' => $proper_filename )
     2430    return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
    23632431}
    23642432
Note: See TracChangeset for help on using the changeset viewer.