wp_check_filetype_and_ext() WordPress Function
The wp_check_filetype_and_ext() function is used to check the filetype and extension of a given file. This function is useful for validating and verifying the filetype and extension of a given file.
wp_check_filetype_and_ext( string $file, string $filename, string[] $mimes = null ) #
Attempt to determine the real file type of a file.
Description
If unable to, the file name extension will be used to determine type.
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 renaming images validated via wp_get_image_mime().
Parameters
- $file
(string)(Required)Full path to the file.
- $filename
(string)(Required)The name of the file (may differ from $file due to $file being in a tmp directory).
- $mimes
(string[])(Optional) Array of allowed mime types keyed by their file extension regex.
Default value: null
Return
(array) Values for the extension, mime type, and corrected filename.
- 'ext'
(string|false) File extension, or false if the file doesn't match a mime type. - 'type'
(string|false) File mime type, or false if the file doesn't match a mime type. - 'proper_filename'
(string|false) File name with its correct extension, or false if it cannot be determined.
More Information
Usage:
$validate = wp_check_filetype_and_ext( $file, $filename, $mimes ); if( $validate['proper_filename'] !== false ) $filename = $validate['proper_filename'];
Notes:
Currently, this function only supports validating images known to getimagesize().
If using in a plugin/theme and you get an error about this function not being defined, you probably need to add require_once ABSPATH .'wp-admin/includes/file.php';
before the function gets called.
Source
File: wp-includes/functions.php
function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) { $proper_filename = false; // Do basic extension validation and MIME mapping. $wp_filetype = wp_check_filetype( $filename, $mimes ); $ext = $wp_filetype['ext']; $type = $wp_filetype['type']; // We can't do any further validation without a file to work with. if ( ! file_exists( $file ) ) { return compact( 'ext', 'type', 'proper_filename' ); } $real_mime = false; // Validate image types. if ( $type && 0 === strpos( $type, 'image/' ) ) { // Attempt to figure out what type of image it actually is. $real_mime = wp_get_image_mime( $file ); if ( $real_mime && $real_mime != $type ) { /** * Filters the list mapping image mime types to their respective extensions. * * @since 3.0.0 * * @param array $mime_to_ext Array of image mime types and their matching extensions. */ $mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array( 'image/jpeg' => 'jpg', 'image/png' => 'png', 'image/gif' => 'gif', 'image/bmp' => 'bmp', 'image/tiff' => 'tif', 'image/webp' => 'webp', ) ); // Replace whatever is after the last period in the filename with the correct extension. if ( ! empty( $mime_to_ext[ $real_mime ] ) ) { $filename_parts = explode( '.', $filename ); array_pop( $filename_parts ); $filename_parts[] = $mime_to_ext[ $real_mime ]; $new_filename = implode( '.', $filename_parts ); if ( $new_filename != $filename ) { $proper_filename = $new_filename; // Mark that it changed. } // Redefine the extension / MIME. $wp_filetype = wp_check_filetype( $new_filename, $mimes ); $ext = $wp_filetype['ext']; $type = $wp_filetype['type']; } else { // Reset $real_mime and try validating again. $real_mime = false; } } } // Validate files that didn't get validated during previous checks. if ( $type && ! $real_mime && extension_loaded( 'fileinfo' ) ) { $finfo = finfo_open( FILEINFO_MIME_TYPE ); $real_mime = finfo_file( $finfo, $file ); finfo_close( $finfo ); // fileinfo often misidentifies obscure files as one of these types. $nonspecific_types = array( 'application/octet-stream', 'application/encrypted', 'application/CDFV2-encrypted', 'application/zip', ); /* * If $real_mime doesn't match the content type we're expecting from the file's extension, * we need to do some additional vetting. Media types and those listed in $nonspecific_types are * allowed some leeway, but anything else must exactly match the real content type. */ if ( in_array( $real_mime, $nonspecific_types, true ) ) { // File is a non-specific binary type. That's ok if it's a type that generally tends to be binary. if ( ! in_array( substr( $type, 0, strcspn( $type, '/' ) ), array( 'application', 'video', 'audio' ), true ) ) { $type = false; $ext = false; } } elseif ( 0 === strpos( $real_mime, 'video/' ) || 0 === strpos( $real_mime, 'audio/' ) ) { /* * For these types, only the major type must match the real value. * This means that common mismatches are forgiven: application/vnd.apple.numbers is often misidentified as application/zip, * and some media files are commonly named with the wrong extension (.mov instead of .mp4) */ if ( substr( $real_mime, 0, strcspn( $real_mime, '/' ) ) !== substr( $type, 0, strcspn( $type, '/' ) ) ) { $type = false; $ext = false; } } elseif ( 'text/plain' === $real_mime ) { // A few common file types are occasionally detected as text/plain; allow those. if ( ! in_array( $type, array( 'text/plain', 'text/csv', 'application/csv', 'text/richtext', 'text/tsv', 'text/vtt', ), true ) ) { $type = false; $ext = false; } } elseif ( 'application/csv' === $real_mime ) { // Special casing for CSV files. if ( ! in_array( $type, array( 'text/csv', 'text/plain', 'application/csv', ), true ) ) { $type = false; $ext = false; } } elseif ( 'text/rtf' === $real_mime ) { // Special casing for RTF files. if ( ! in_array( $type, array( 'text/rtf', 'text/plain', 'application/rtf', ), true ) ) { $type = false; $ext = false; } } else { if ( $type !== $real_mime ) { /* * Everything else including image/* and application/*: * If the real content type doesn't match the file extension, assume it's dangerous. */ $type = false; $ext = false; } } } // The mime type must be allowed. if ( $type ) { $allowed = get_allowed_mime_types(); if ( ! in_array( $type, $allowed, true ) ) { $type = false; $ext = false; } } /** * Filters the "real" file type of the given file. * * @since 3.0.0 * @since 5.1.0 The $real_mime parameter was added. * * @param array $wp_check_filetype_and_ext { * Values for the extension, mime type, and corrected filename. * * @type string|false $ext File extension, or false if the file doesn't match a mime type. * @type string|false $type File mime type, or false if the file doesn't match a mime type. * @type string|false $proper_filename File name with its correct extension, or false if it cannot be determined. * } * @param string $file Full path to the file. * @param string $filename The name of the file (may differ from $file due to * $file being in a tmp directory). * @param string[] $mimes Array of mime types keyed by their file extension regex. * @param string|false $real_mime The actual mime type or false if the type cannot be determined. */ return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes, $real_mime ); }
Expand full source codeCollapse full source codeView on TracView on GitHub
Changelog
Version | Description |
---|---|
3.0.0 | Introduced. |