Media: Reduce failing uploads following 4.7.1.
[39831] introduced more strict MIME type checking for uploads, which resulted in unintetionally blocking several filetypes that were previously valid. This change uses a more targeted approach to MIME validation to restore previous behavior for most types. Props blobfolio, iandunn, ipstenu, markoheijnen, xknown, joemcgill. Fixes #39550, #39552. git-svn-id: https://develop.svn.wordpress.org/trunk@40124 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
cfe271d254
commit
7684a241b3
@ -2269,15 +2269,15 @@ function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
|
||||
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 ) {
|
||||
$type = $ext = false;
|
||||
} elseif ( $real_mime != $type ) {
|
||||
if ( $real_mime && $real_mime != $type ) {
|
||||
/**
|
||||
* Filters the list mapping image mime types to their respective extensions.
|
||||
*
|
||||
@ -2308,18 +2308,29 @@ function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
|
||||
$ext = $wp_filetype['ext'];
|
||||
$type = $wp_filetype['type'];
|
||||
} else {
|
||||
$type = $ext = false;
|
||||
// Reset $real_mime and try validating again.
|
||||
$real_mime = false;
|
||||
}
|
||||
}
|
||||
} elseif ( function_exists( 'finfo_file' ) ) {
|
||||
// Use finfo_file if available to validate non-image files.
|
||||
}
|
||||
|
||||
// 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 );
|
||||
|
||||
// If the extension does not match the file's real type, return false.
|
||||
if ( $real_mime !== $type ) {
|
||||
$type = $ext = false;
|
||||
/*
|
||||
* If $real_mime doesn't match what we're expecting, we need to do some extra
|
||||
* vetting of application mime types to make sure this type of file is allowed.
|
||||
* Other mime types are assumed to be safe, but should be considered unverified.
|
||||
*/
|
||||
if ( $real_mime && ( $real_mime !== $type ) && ( 0 === strpos( $real_mime, 'application' ) ) ) {
|
||||
$allowed = get_allowed_mime_types();
|
||||
|
||||
if ( ! in_array( $real_mime, $allowed ) ) {
|
||||
$type = $ext = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
BIN
tests/phpunit/data/uploads/dashicons.woff
Normal file
BIN
tests/phpunit/data/uploads/dashicons.woff
Normal file
Binary file not shown.
BIN
tests/phpunit/data/uploads/pages-to-word.docx
Normal file
BIN
tests/phpunit/data/uploads/pages-to-word.docx
Normal file
Binary file not shown.
5
tests/phpunit/data/uploads/video-play.svg
Normal file
5
tests/phpunit/data/uploads/video-play.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="64" height="64">
|
||||
<circle cx="32" cy="32" r="25" stroke="white" stroke-width="7" fill="black" fill-opacity="0.2"/>
|
||||
<polygon points="26,22 26,42 43,32" fill="white"/>
|
||||
</svg>
|
After Width: | Height: | Size: 274 B |
@ -914,4 +914,141 @@ class Tests_Functions extends WP_UnitTestCase {
|
||||
$unique_uuids = array_unique( $uuids );
|
||||
$this->assertEquals( $uuids, $unique_uuids );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 39550
|
||||
* @dataProvider _wp_check_filetype_and_ext_data
|
||||
*/
|
||||
function test_wp_check_filetype_and_ext( $file, $filename, $expected ) {
|
||||
if ( ! extension_loaded( 'fileinfo' ) ) {
|
||||
$this->markTestSkipped( 'The fileinfo PHP extension is not loaded.' );
|
||||
}
|
||||
|
||||
$this->assertEquals( $expected, wp_check_filetype_and_ext( $file, $filename ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 39550
|
||||
*/
|
||||
function test_wp_check_filetype_and_ext_with_filtered_svg() {
|
||||
$file = DIR_TESTDATA . '/uploads/video-play.svg';
|
||||
$filename = 'video-play.svg';
|
||||
|
||||
$expected = array(
|
||||
'ext' => 'svg',
|
||||
'type' => 'image/svg+xml',
|
||||
'proper_filename' => false,
|
||||
);
|
||||
|
||||
add_filter( 'upload_mimes', array( $this, '_filter_mime_types_svg' ) );
|
||||
$this->assertEquals( $expected, wp_check_filetype_and_ext( $file, $filename ) );
|
||||
|
||||
// Cleanup.
|
||||
remove_filter( 'upload_mimes', array( $this, '_test_add_mime_types_svg' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 39550
|
||||
*/
|
||||
function test_wp_check_filetype_and_ext_with_filtered_woff() {
|
||||
$file = DIR_TESTDATA . '/uploads/dashicons.woff';
|
||||
$filename = 'dashicons.woff';
|
||||
|
||||
$expected = array(
|
||||
'ext' => 'woff',
|
||||
'type' => 'application/font-woff',
|
||||
'proper_filename' => false,
|
||||
);
|
||||
|
||||
add_filter( 'upload_mimes', array( $this, '_filter_mime_types_woff' ) );
|
||||
$this->assertEquals( $expected, wp_check_filetype_and_ext( $file, $filename ) );
|
||||
|
||||
// Cleanup.
|
||||
remove_filter( 'upload_mimes', array( $this, '_test_add_mime_types_woff' ) );
|
||||
}
|
||||
|
||||
public function _filter_mime_types_svg( $mimes ) {
|
||||
$mimes['svg'] = 'image/svg+xml';
|
||||
return $mimes;
|
||||
}
|
||||
|
||||
public function _filter_mime_types_woff( $mimes ) {
|
||||
$mimes['woff'] = 'application/font-woff';
|
||||
return $mimes;
|
||||
}
|
||||
|
||||
public function _wp_check_filetype_and_ext_data() {
|
||||
return array(
|
||||
// Standard image.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/canola.jpg',
|
||||
'canola.jpg',
|
||||
array(
|
||||
'ext' => 'jpg',
|
||||
'type' => 'image/jpeg',
|
||||
'proper_filename' => false,
|
||||
),
|
||||
),
|
||||
// Image with wrong extension.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/test-image-mime-jpg.png',
|
||||
'test-image-mime-jpg.png',
|
||||
array(
|
||||
'ext' => 'jpg',
|
||||
'type' => 'image/jpeg',
|
||||
'proper_filename' => 'test-image-mime-jpg.jpg',
|
||||
),
|
||||
),
|
||||
// Image without extension.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/test-image-no-extension',
|
||||
'test-image-no-extension',
|
||||
array(
|
||||
'ext' => false,
|
||||
'type' => false,
|
||||
'proper_filename' => false,
|
||||
),
|
||||
),
|
||||
// Valid non-image file with an image extension.
|
||||
array(
|
||||
DIR_TESTDATA . '/formatting/big5.txt',
|
||||
'big5.jpg',
|
||||
array(
|
||||
'ext' => 'jpg',
|
||||
'type' => 'image/jpeg',
|
||||
'proper_filename' => false,
|
||||
),
|
||||
),
|
||||
// Standard non-image file.
|
||||
array(
|
||||
DIR_TESTDATA . '/formatting/big5.txt',
|
||||
'big5.txt',
|
||||
array(
|
||||
'ext' => 'txt',
|
||||
'type' => 'text/plain',
|
||||
'proper_filename' => false,
|
||||
),
|
||||
),
|
||||
// Non-image file with wrong sub-type.
|
||||
array(
|
||||
DIR_TESTDATA . '/uploads/pages-to-word.docx',
|
||||
'pages-to-word.docx',
|
||||
array(
|
||||
'ext' => 'docx',
|
||||
'type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'proper_filename' => false,
|
||||
),
|
||||
),
|
||||
// Non-image file not allowed.
|
||||
array(
|
||||
DIR_TESTDATA . '/export/crazy-cdata.xml',
|
||||
'crazy-cdata.xml',
|
||||
array(
|
||||
'ext' => false,
|
||||
'type' => false,
|
||||
'proper_filename' => false,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user