WordPress.org

Make WordPress Core

Ticket #40175: 40175.2.diff

File 40175.2.diff, 11.3 KB (added by blobfolio, 21 months ago)

Rebuilt patch against current src

  • src/wp-includes/functions.php

    diff --git src/wp-includes/functions.php src/wp-includes/functions.php
    index 2720f590af..69e1319a84 100644
    function _wp_upload_dir( $time = null ) { 
    20232023}
    20242024
    20252025/**
     2026 * Assign a new extension to a filename.
     2027 *
     2028 * @since 4.9
     2029 *
     2030 * @param string $filename The original filename.
     2031 * @param string $ext      The new extension.
     2032 * @return string The renamed file.
     2033 */
     2034function wp_update_filename_extension( $filename, $ext ) {
     2035        $ext = strtolower( $ext );
     2036        $ext = rtrim( $ext, '.' );
     2037        $ext = ltrim( $ext, '.' );
     2038
     2039        $filename_parts = explode( '.', $filename );
     2040
     2041        // Remove the old extension.
     2042        if ( count( $filename_parts ) > 1 ) {
     2043                array_pop( $filename_parts );
     2044        }
     2045
     2046        // Add the new extension.
     2047        if ( strlen( $ext ) ) {
     2048                $filename_parts[] = $ext;
     2049        }
     2050
     2051        return implode( '.', $filename_parts );
     2052}
     2053
     2054/**
    20262055 * Get a filename that is sanitized and unique for the given directory.
    20272056 *
    20282057 * If the filename is not unique, then a number will be added to the filename
    function wp_check_filetype( $filename, $mimes = null ) { 
    22672296function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
    22682297        $proper_filename = false;
    22692298
    2270         // Do basic extension validation and MIME mapping
     2299        // Do basic extension validation and MIME mapping.
    22712300        $wp_filetype = wp_check_filetype( $filename, $mimes );
    22722301        $ext = $wp_filetype['ext'];
    22732302        $type = $wp_filetype['type'];
    22742303
    2275         // We can't do any further validation without a file to work with
     2304        // We can't do any further validation without a file to work with.
    22762305        if ( ! file_exists( $file ) ) {
    22772306                return compact( 'ext', 'type', 'proper_filename' );
    22782307        }
    function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) { 
    22822311        // Validate image types.
    22832312        if ( $type && 0 === strpos( $type, 'image/' ) ) {
    22842313
    2285                 // Attempt to figure out what type of image it actually is
     2314                // Attempt to figure out what type of image it actually is.
    22862315                $real_mime = wp_get_image_mime( $file );
    22872316
    22882317                if ( $real_mime && $real_mime != $type ) {
    function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) { 
    22942323                         * @param  array $mime_to_ext Array of image mime types and their matching extensions.
    22952324                         */
    22962325                        $mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(
    2297                                 'image/jpeg' => 'jpg',
    2298                                 'image/png'  => 'png',
    2299                                 'image/gif'  => 'gif',
    2300                                 'image/bmp'  => 'bmp',
    2301                                 'image/tiff' => 'tif',
     2326                                'image/jpeg'      => 'jpg',
     2327                                'image/png'       => 'png',
     2328                                'image/gif'       => 'gif',
     2329                                'image/bmp'       => 'bmp',
     2330                                'image/x-ms-bmp'  => 'bmp',
     2331                                'image/tiff'      => 'tif',
    23022332                        ) );
    23032333
    2304                         // Replace whatever is after the last period in the filename with the correct extension
     2334                        // Rename the file with the correct extension.
    23052335                        if ( ! empty( $mime_to_ext[ $real_mime ] ) ) {
    2306                                 $filename_parts = explode( '.', $filename );
    2307                                 array_pop( $filename_parts );
    2308                                 $filename_parts[] = $mime_to_ext[ $real_mime ];
    2309                                 $new_filename = implode( '.', $filename_parts );
     2336                                $new_filename = wp_update_filename_extension( $filename, $mime_to_ext[ $real_mime ] );
    23102337
    23112338                                if ( $new_filename != $filename ) {
    2312                                         $proper_filename = $new_filename; // Mark that it changed
     2339                                        $proper_filename = $new_filename; // Mark that it changed.
    23132340                                }
    23142341                                // Redefine the extension / MIME
    23152342                                $wp_filetype = wp_check_filetype( $new_filename, $mimes );
    function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) { 
    23232350        }
    23242351
    23252352        // Validate files that didn't get validated during previous checks.
    2326         if ( $type && ! $real_mime && extension_loaded( 'fileinfo' ) ) {
     2353        if (
     2354                $type &&
     2355                ! $real_mime &&
     2356                extension_loaded( 'fileinfo' ) &&
     2357                defined( 'FILEINFO_MIME_TYPE' )
     2358        ) {
    23272359                $finfo = finfo_open( FILEINFO_MIME_TYPE );
    23282360                $real_mime = finfo_file( $finfo, $file );
    23292361                finfo_close( $finfo );
    23302362
    23312363                /*
    23322364                 * If $real_mime doesn't match what we're expecting, we need to do some extra
    2333                  * vetting of application mime types to make sure this type of file is allowed.
     2365                 * vetting of greylisted mime types to make sure this type of file is allowed.
    23342366                 * Other mime types are assumed to be safe, but should be considered unverified.
    23352367                 */
    2336                 if ( $real_mime && ( $real_mime !== $type ) && ( 0 === strpos( $real_mime, 'application' ) ) ) {
    2337                         $allowed = get_allowed_mime_types();
     2368                if ( $real_mime && ( $real_mime !== $type ) ) {
     2369                        // Get the true file extension for a greylisted filetype.
     2370                        $greylist = get_greylisted_mime_types();
     2371                        $real_mime = strtolower( sanitize_mime_type( $real_mime ) );
     2372                        $real_ext = false;
     2373                        foreach ( $greylist as $exts => $greylist_types ) {
     2374                                if ( in_array( $real_mime, $greylist_types, true ) ) {
     2375                                        $real_ext = $exts;
     2376                                        break;
     2377                                }
     2378                        }
     2379
     2380                        if ( $real_ext ) {
     2381                                // This MIME type is greylisted, so make sure the extension is allowed.
     2382                                $allowed = get_allowed_mime_types();
     2383                                $found = false;
     2384                                foreach ( $allowed as $exts => $allowed_type ) {
     2385                                        $exts = explode( '|', $exts );
     2386                                        if ( in_array( $real_ext, $exts, true ) ) {
     2387                                                // Rename the file with the correct extension.
     2388                                                if ( $ext !== $real_ext ) {
     2389                                                        $new_filename = wp_update_filename_extension( $filename, $real_ext );
     2390
     2391                                                        if ( $new_filename != $filename ) {
     2392                                                                $proper_filename = $new_filename; // Mark that it changed.
     2393                                                        }
     2394
     2395                                                        $ext = $real_ext;
     2396                                                }
    23382397
    2339                         if ( ! in_array( $real_mime, $allowed ) ) {
    2340                                 $type = $ext = false;
     2398                                                // Always prefer the MIME type from get_allowed_mimes().
     2399                                                $type = $allowed_type;
     2400
     2401                                                $found = true;
     2402                                                break;
     2403                                        }
     2404                                }
     2405
     2406                                // Unauthorized file.
     2407                                if ( ! $found ) {
     2408                                        $ext = $type = false;
     2409                                }
    23412410                        }
    23422411                }
    23432412        }
    function wp_get_ext_types() { 
    25462615}
    25472616
    25482617/**
     2618 * Retrieve list of greylisted mime types and file extensions.
     2619 *
     2620 * These are file types deserving of extra validation during uploads. Unlike
     2621 * get_allowed_mime_types, each entry consists of a single file extension
     2622 * with multiple MIME types.
     2623 *
     2624 * @since 4.9
     2625 *
     2626 * @return array Array of mime types keyed by the file extension corresponding
     2627 *               to those types.
     2628 */
     2629function get_greylisted_mime_types() {
     2630        $greylist = array(
     2631                'air' => array(
     2632                        'application/adobe.air-application-installer-package+zip',
     2633                        'application/vnd.adobe.air-application-installer-package+zip',
     2634                        'application/x-adobe.air-application-installer-package+zip',
     2635                ),
     2636                'fla' => array(
     2637                        'application/dtg.local.flash',
     2638                        'application/vnd.dtg.local.flash',
     2639                        'application/x-dtg.local.flash',
     2640                ),
     2641                'flv' => array(
     2642                        'application/flash-video',
     2643                        'application/vnd.flash-video',
     2644                        'application/x-flash-video',
     2645                        'flv-application/octet-stream',
     2646                        'video/flv',
     2647                        'video/x-flv',
     2648                ),
     2649                'swf' => array(
     2650                        'application/adobe.flash.movie',
     2651                        'application/futuresplash',
     2652                        'application/shockwave-flash',
     2653                        'application/vnd.adobe.flash.movie',
     2654                        'application/vnd.futuresplash',
     2655                        'application/vnd.shockwave-flash',
     2656                        'application/x-adobe.flash.movie',
     2657                        'application/x-futuresplash',
     2658                        'application/x-shockwave-flash',
     2659                ),
     2660                'spl' => array(
     2661                        'application/adobe.flash.movie',
     2662                        'application/futuresplash',
     2663                        'application/shockwave-flash',
     2664                        'application/vnd.adobe.flash.movie',
     2665                        'application/vnd.futuresplash',
     2666                        'application/vnd.shockwave-flash',
     2667                        'application/x-adobe.flash.movie',
     2668                        'application/x-futuresplash',
     2669                        'application/x-shockwave-flash',
     2670                ),
     2671        );
     2672
     2673        /**
     2674         * Filters the greylist results.
     2675         *
     2676         * @since 4.9
     2677         *
     2678         * @param array $greylist Array of mime types keyed by the file extension corresponding
     2679         *                        to those types.
     2680         */
     2681        return apply_filters( 'get_greylisted_mime_types', $greylist );
     2682}
     2683
     2684/**
    25492685 * Retrieve list of allowed mime types and file extensions.
    25502686 *
    25512687 * @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 7c8736ab67..778071b6e3 100644
    class Tests_Functions extends WP_UnitTestCase { 
    122122                );
    123123        }
    124124
     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
    125132        function test_wp_unique_filename() {
    126133
    127134                $testdir = DIR_TESTDATA . '/images/';
    class Tests_Functions extends WP_UnitTestCase { 
    10441051        }
    10451052
    10461053        /**
     1054         * @ticket 39550
     1055         *
     1056         * @dataProvider _wp_check_filetype_and_ext_with_filtered_swf
     1057         */
     1058        function test_wp_check_filetype_and_ext_with_filtered_swf( $file, $filename, $expected ) {
     1059                if ( ! extension_loaded( 'fileinfo' ) ) {
     1060                        $this->markTestSkipped( 'The fileinfo PHP extension is not loaded.' );
     1061                }
     1062
     1063                if ( is_multisite() ) {
     1064                        $this->markTestSkipped( 'Test does not run in multisite' );
     1065                }
     1066
     1067                add_filter( 'upload_mimes', array( $this, '_filter_mime_types_swf' ) );
     1068                $this->assertEquals( $expected, wp_check_filetype_and_ext( $file, $filename ) );
     1069
     1070                // Cleanup.
     1071                remove_filter( 'upload_mimes', array( $this, '_test_add_mime_types_swf' ) );
     1072        }
     1073
     1074        /**
    10471075         * Data profider for test_wp_get_image_mime();
    10481076         */
    10491077        public function _wp_get_image_mime() {
    class Tests_Functions extends WP_UnitTestCase { 
    11301158                                        'proper_filename' => false,
    11311159                                ),
    11321160                        ),
     1161                        // Flash file with invalid extension.
     1162                        array(
     1163                                DIR_TESTDATA . '/uploads/test.swf',
     1164                                'big5.jpg',
     1165                                array(
     1166                                        'ext' => false,
     1167                                        'type' => false,
     1168                                        'proper_filename' => false,
     1169                                ),
     1170                        ),
     1171                        // Flash file with valid extension.
     1172                        array(
     1173                                DIR_TESTDATA . '/uploads/test.swf',
     1174                                'test.swf',
     1175                                array(
     1176                                        'ext' => false,
     1177                                        'type' => false,
     1178                                        'proper_filename' => false,
     1179                                ),
     1180                        ),
    11331181                );
    11341182
    11351183                // Test a few additional file types on single sites.
    class Tests_Functions extends WP_UnitTestCase { 
    11611209                return $data;
    11621210        }
    11631211
     1212        public function _filter_mime_types_swf( $mimes ) {
     1213                $mimes['swf'] = 'application/x-shockwave-flash';
     1214                return $mimes;
     1215        }
     1216
     1217        public function _wp_update_filename_extension() {
     1218                $data = array(
     1219                        array(
     1220                                'test.jpg',
     1221                                'png',
     1222                                'test.png',
     1223                        ),
     1224                        array(
     1225                                'test',
     1226                                'png',
     1227                                'test.png',
     1228                        ),
     1229                        array(
     1230                                'test',
     1231                                '.png',
     1232                                'test.png',
     1233                        ),
     1234                        array(
     1235                                'test.jpg',
     1236                                '',
     1237                                'test',
     1238                        ),
     1239                );
     1240
     1241                return $data;
     1242        }
     1243
     1244        public function _wp_check_filetype_and_ext_with_filtered_swf() {
     1245                $data = array(
     1246                        // Correctly named SWF.
     1247                        array(
     1248                                DIR_TESTDATA . '/uploads/test.swf',
     1249                                'test.swf',
     1250                                array(
     1251                                        'ext' => 'swf',
     1252                                        'type' => 'application/x-shockwave-flash',
     1253                                        'proper_filename' => false,
     1254                                ),
     1255                        ),
     1256                        // Incorrectly named SWF.
     1257                        array(
     1258                                DIR_TESTDATA . '/uploads/test.swf',
     1259                                'test.jpg',
     1260                                array(
     1261                                        'ext' => 'swf',
     1262                                        'type' => 'application/x-shockwave-flash',
     1263                                        'proper_filename' => 'test.swf',
     1264                                ),
     1265                        ),
     1266                );
     1267
     1268                return $data;
     1269        }
    11641270}