Ticket #40175: 40175.diff
| File 40175.diff, 11.3 KB (added by , 9 years ago) |
|---|
-
src/wp-includes/functions.php
diff --git src/wp-includes/functions.php src/wp-includes/functions.php index ebdc12344c..73d9b6e6d1 100644
function _wp_upload_dir( $time = null ) { 2017 2017 } 2018 2018 2019 2019 /** 2020 * Assign a new extension to a filename. 2021 * 2022 * @since 4.8.1 2023 * 2024 * @param string $filename The original filename. 2025 * @param string $ext The new extension. 2026 * @return string The renamed file. 2027 */ 2028 function wp_update_filename_extension( $filename, $ext ) { 2029 $ext = strtolower( $ext ); 2030 $ext = rtrim( $ext, '.' ); 2031 $ext = ltrim( $ext, '.' ); 2032 2033 $filename_parts = explode( '.', $filename ); 2034 2035 // Remove the old extension. 2036 if ( count( $filename_parts ) > 1 ) { 2037 array_pop( $filename_parts ); 2038 } 2039 2040 // Add the new extension. 2041 if ( strlen( $ext ) ) { 2042 $filename_parts[] = $ext; 2043 } 2044 2045 return implode( '.', $filename_parts ); 2046 } 2047 2048 /** 2020 2049 * Get a filename that is sanitized and unique for the given directory. 2021 2050 * 2022 2051 * If the filename is not unique, then a number will be added to the filename … … function wp_check_filetype( $filename, $mimes = null ) { 2261 2290 function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) { 2262 2291 $proper_filename = false; 2263 2292 2264 // Do basic extension validation and MIME mapping 2293 // Do basic extension validation and MIME mapping. 2265 2294 $wp_filetype = wp_check_filetype( $filename, $mimes ); 2266 2295 $ext = $wp_filetype['ext']; 2267 2296 $type = $wp_filetype['type']; 2268 2297 2269 // We can't do any further validation without a file to work with 2298 // We can't do any further validation without a file to work with. 2270 2299 if ( ! file_exists( $file ) ) { 2271 2300 return compact( 'ext', 'type', 'proper_filename' ); 2272 2301 } … … function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) { 2276 2305 // Validate image types. 2277 2306 if ( $type && 0 === strpos( $type, 'image/' ) ) { 2278 2307 2279 // Attempt to figure out what type of image it actually is 2308 // Attempt to figure out what type of image it actually is. 2280 2309 $real_mime = wp_get_image_mime( $file ); 2281 2310 2282 2311 if ( $real_mime && $real_mime != $type ) { … … function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) { 2288 2317 * @param array $mime_to_ext Array of image mime types and their matching extensions. 2289 2318 */ 2290 2319 $mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array( 2291 'image/jpeg' => 'jpg', 2292 'image/png' => 'png', 2293 'image/gif' => 'gif', 2294 'image/bmp' => 'bmp', 2295 'image/tiff' => 'tif', 2320 'image/jpeg' => 'jpg', 2321 'image/png' => 'png', 2322 'image/gif' => 'gif', 2323 'image/bmp' => 'bmp', 2324 'image/x-ms-bmp' => 'bmp', 2325 'image/tiff' => 'tif', 2296 2326 ) ); 2297 2327 2298 // Re place whatever is after the last period in the filename with the correct extension2328 // Rename the file with the correct extension. 2299 2329 if ( ! empty( $mime_to_ext[ $real_mime ] ) ) { 2300 $filename_parts = explode( '.', $filename ); 2301 array_pop( $filename_parts ); 2302 $filename_parts[] = $mime_to_ext[ $real_mime ]; 2303 $new_filename = implode( '.', $filename_parts ); 2330 $new_filename = wp_update_filename_extension( $filename, $mime_to_ext[ $real_mime ] ); 2304 2331 2305 2332 if ( $new_filename != $filename ) { 2306 $proper_filename = $new_filename; // Mark that it changed 2333 $proper_filename = $new_filename; // Mark that it changed. 2307 2334 } 2308 2335 // Redefine the extension / MIME 2309 2336 $wp_filetype = wp_check_filetype( $new_filename, $mimes ); … … function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) { 2317 2344 } 2318 2345 2319 2346 // Validate files that didn't get validated during previous checks. 2320 if ( $type && ! $real_mime && extension_loaded( 'fileinfo' ) ) { 2347 if ( 2348 $type && 2349 ! $real_mime && 2350 extension_loaded( 'fileinfo' ) && 2351 defined( 'FILEINFO_MIME_TYPE' ) 2352 ) { 2321 2353 $finfo = finfo_open( FILEINFO_MIME_TYPE ); 2322 2354 $real_mime = finfo_file( $finfo, $file ); 2323 2355 finfo_close( $finfo ); 2324 2356 2325 2357 /* 2326 2358 * If $real_mime doesn't match what we're expecting, we need to do some extra 2327 * vetting of applicationmime types to make sure this type of file is allowed.2359 * vetting of greylisted mime types to make sure this type of file is allowed. 2328 2360 * Other mime types are assumed to be safe, but should be considered unverified. 2329 2361 */ 2330 if ( $real_mime && ( $real_mime !== $type ) && ( 0 === strpos( $real_mime, 'application' ) ) ) { 2331 $allowed = get_allowed_mime_types(); 2362 if ( $real_mime && ( $real_mime !== $type ) ) { 2363 // Get the true file extension for a greylisted filetype. 2364 $greylist = get_greylisted_mime_types(); 2365 $real_mime = strtolower( sanitize_mime_type( $real_mime ) ); 2366 $real_ext = false; 2367 foreach ( $greylist as $exts => $greylist_types ) { 2368 if ( in_array( $real_mime, $greylist_types, true ) ) { 2369 $real_ext = $exts; 2370 break; 2371 } 2372 } 2373 2374 if ( $real_ext ) { 2375 // This MIME type is greylisted, so make sure the extension is allowed. 2376 $allowed = get_allowed_mime_types(); 2377 $found = false; 2378 foreach ( $allowed as $exts => $allowed_type ) { 2379 $exts = explode( '|', $exts ); 2380 if ( in_array( $real_ext, $exts, true ) ) { 2381 // Rename the file with the correct extension. 2382 if ( $ext !== $real_ext ) { 2383 $new_filename = wp_update_filename_extension( $filename, $real_ext ); 2384 2385 if ( $new_filename != $filename ) { 2386 $proper_filename = $new_filename; // Mark that it changed. 2387 } 2388 2389 $ext = $real_ext; 2390 } 2332 2391 2333 if ( ! in_array( $real_mime, $allowed ) ) { 2334 $type = $ext = false; 2392 // Always prefer the MIME type from get_allowed_mimes(). 2393 $type = $allowed_type; 2394 2395 $found = true; 2396 break; 2397 } 2398 } 2399 2400 // Unauthorized file. 2401 if ( ! $found ) { 2402 $ext = $type = false; 2403 } 2335 2404 } 2336 2405 } 2337 2406 } … … function wp_get_ext_types() { 2540 2609 } 2541 2610 2542 2611 /** 2612 * Retrieve list of greylisted mime types and file extensions. 2613 * 2614 * These are file types deserving of extra validation during uploads. Unlike 2615 * get_allowed_mime_types, each entry consists of a single file extension 2616 * with multiple MIME types. 2617 * 2618 * @since 4.8.1 2619 * 2620 * @return array Array of mime types keyed by the file extension corresponding 2621 * to those types. 2622 */ 2623 function get_greylisted_mime_types() { 2624 $greylist = array( 2625 'air' => array( 2626 'application/adobe.air-application-installer-package+zip', 2627 'application/vnd.adobe.air-application-installer-package+zip', 2628 'application/x-adobe.air-application-installer-package+zip', 2629 ), 2630 'fla' => array( 2631 'application/dtg.local.flash', 2632 'application/vnd.dtg.local.flash', 2633 'application/x-dtg.local.flash', 2634 ), 2635 'flv' => array( 2636 'application/flash-video', 2637 'application/vnd.flash-video', 2638 'application/x-flash-video', 2639 'flv-application/octet-stream', 2640 'video/flv', 2641 'video/x-flv', 2642 ), 2643 'swf' => array( 2644 'application/adobe.flash.movie', 2645 'application/futuresplash', 2646 'application/shockwave-flash', 2647 'application/vnd.adobe.flash.movie', 2648 'application/vnd.futuresplash', 2649 'application/vnd.shockwave-flash', 2650 'application/x-adobe.flash.movie', 2651 'application/x-futuresplash', 2652 'application/x-shockwave-flash', 2653 ), 2654 'spl' => array( 2655 'application/adobe.flash.movie', 2656 'application/futuresplash', 2657 'application/shockwave-flash', 2658 'application/vnd.adobe.flash.movie', 2659 'application/vnd.futuresplash', 2660 'application/vnd.shockwave-flash', 2661 'application/x-adobe.flash.movie', 2662 'application/x-futuresplash', 2663 'application/x-shockwave-flash', 2664 ), 2665 ); 2666 2667 /** 2668 * Filters the greylist results. 2669 * 2670 * @since 4.8.1 2671 * 2672 * @param array $greylist Array of mime types keyed by the file extension corresponding 2673 * to those types. 2674 */ 2675 return apply_filters( 'get_greylisted_mime_types', $greylist ); 2676 } 2677 2678 /** 2543 2679 * Retrieve list of allowed mime types and file extensions. 2544 2680 * 2545 2681 * @since 2.8.6 -
new file tests/phpunit/data/uploads/test.swf
diff --git tests/phpunit/data/uploads/test.swf tests/phpunit/data/uploads/test.swf new file mode 100644 index 0000000000000000000000000000000000000000..c6195c41eebe7b3b2006eff39a268320e973feac GIT binary patch literal 140 zcmZ<@4`%OSU|^_VV2x*B;9tPNz{AL3&zuVs>d;|eVaQD_E>28OWk@bcO)N<bNv$Yx z%S_ElVJHEz7(7yQa`F|z^NVs)6d9&zF|Zo}wXvrF2{s@G12}`75y<CYU<V0sFxrYw UV*>JIrm-+^FmW*ZGdKW+0pm9pO8@`> -
tests/phpunit/tests/functions.php
literal 0 HcmV?d00001 diff --git tests/phpunit/tests/functions.php tests/phpunit/tests/functions.php index 252d890bbb..4205f8a139 100644
class Tests_Functions extends WP_UnitTestCase { 122 122 ); 123 123 } 124 124 125 /** 126 * @dataProvider _wp_update_filename_extension 127 */ 128 function test_wp_update_filename_extension( $filename, $ext, $expected ) { 129 $this->assertEquals( $expected, wp_update_filename_extension( $filename, $ext ) ); 130 } 131 125 132 function test_wp_unique_filename() { 126 133 127 134 $testdir = DIR_TESTDATA . '/images/'; … … class Tests_Functions extends WP_UnitTestCase { 994 1001 } 995 1002 996 1003 /** 1004 * @ticket 39550 1005 * 1006 * @dataProvider _wp_check_filetype_and_ext_with_filtered_swf 1007 */ 1008 function test_wp_check_filetype_and_ext_with_filtered_swf( $file, $filename, $expected ) { 1009 if ( ! extension_loaded( 'fileinfo' ) ) { 1010 $this->markTestSkipped( 'The fileinfo PHP extension is not loaded.' ); 1011 } 1012 1013 if ( is_multisite() ) { 1014 $this->markTestSkipped( 'Test does not run in multisite' ); 1015 } 1016 1017 add_filter( 'upload_mimes', array( $this, '_filter_mime_types_swf' ) ); 1018 $this->assertEquals( $expected, wp_check_filetype_and_ext( $file, $filename ) ); 1019 1020 // Cleanup. 1021 remove_filter( 'upload_mimes', array( $this, '_test_add_mime_types_swf' ) ); 1022 } 1023 1024 /** 997 1025 * Data profider for test_wp_get_image_mime(); 998 1026 */ 999 1027 public function _wp_get_image_mime() { … … class Tests_Functions extends WP_UnitTestCase { 1080 1108 'proper_filename' => false, 1081 1109 ), 1082 1110 ), 1111 // Flash file with invalid extension. 1112 array( 1113 DIR_TESTDATA . '/uploads/test.swf', 1114 'big5.jpg', 1115 array( 1116 'ext' => false, 1117 'type' => false, 1118 'proper_filename' => false, 1119 ), 1120 ), 1121 // Flash file with valid extension. 1122 array( 1123 DIR_TESTDATA . '/uploads/test.swf', 1124 'test.swf', 1125 array( 1126 'ext' => false, 1127 'type' => false, 1128 'proper_filename' => false, 1129 ), 1130 ), 1083 1131 ); 1084 1132 1085 1133 // Test a few additional file types on single sites. … … class Tests_Functions extends WP_UnitTestCase { 1110 1158 1111 1159 return $data; 1112 1160 } 1161 1162 public function _filter_mime_types_swf( $mimes ) { 1163 $mimes['swf'] = 'application/x-shockwave-flash'; 1164 return $mimes; 1165 } 1166 1167 public function _wp_update_filename_extension() { 1168 $data = array( 1169 array( 1170 'test.jpg', 1171 'png', 1172 'test.png', 1173 ), 1174 array( 1175 'test', 1176 'png', 1177 'test.png', 1178 ), 1179 array( 1180 'test', 1181 '.png', 1182 'test.png', 1183 ), 1184 array( 1185 'test.jpg', 1186 '', 1187 'test', 1188 ), 1189 ); 1190 1191 return $data; 1192 } 1193 1194 public function _wp_check_filetype_and_ext_with_filtered_swf() { 1195 $data = array( 1196 // Correctly named SWF. 1197 array( 1198 DIR_TESTDATA . '/uploads/test.swf', 1199 'test.swf', 1200 array( 1201 'ext' => 'swf', 1202 'type' => 'application/x-shockwave-flash', 1203 'proper_filename' => false, 1204 ), 1205 ), 1206 // Incorrectly named SWF. 1207 array( 1208 DIR_TESTDATA . '/uploads/test.swf', 1209 'test.jpg', 1210 array( 1211 'ext' => 'swf', 1212 'type' => 'application/x-shockwave-flash', 1213 'proper_filename' => 'test.swf', 1214 ), 1215 ), 1216 ); 1217 1218 return $data; 1219 } 1113 1220 }