Make WordPress Core

Changeset 61416


Ignore:
Timestamp:
12/29/2025 06:59:20 PM (6 weeks ago)
Author:
westonruter
Message:

Script Loader: Warn when a registered style has invalid path data and allow inlining empty stylesheets.

When a stylesheet is registered with a path that does not exist or which is not readable, then a _doing_it_wrong() is now issued. Previously, paths that did not exist were silently skipped; paths for empty styles were also needlessly skipped, since wp_filesize() also returns 0 for the failure case.

Developed in https://github.com/WordPress/wordpress-develop/pull/10653

Follow-up to [50836].

Props westonruter, jonsurrell, soyebsalar01.
See #52620.
Fixes #64447.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/script-loader.php

    r61415 r61416  
    30113011        if ( $path && $src ) {
    30123012            $size = wp_filesize( $path );
    3013             if ( ! $size ) {
     3013            if ( 0 === $size && ! file_exists( $path ) ) {
     3014                _doing_it_wrong(
     3015                    __FUNCTION__,
     3016                    sprintf(
     3017                        /* translators: 1: 'path', 2: filesystem path, 3: style handle */
     3018                        __( 'Unable to read the "%1$s" key with value "%2$s" for stylesheet "%3$s".' ),
     3019                        'path',
     3020                        esc_html( $path ),
     3021                        esc_html( $handle )
     3022                    ),
     3023                    '7.0.0'
     3024                );
    30143025                continue;
    30153026            }
     
    30493060
    30503061            // Get the styles if we don't already have them.
     3062            if ( ! is_readable( $style['path'] ) ) {
     3063                _doing_it_wrong(
     3064                    __FUNCTION__,
     3065                    sprintf(
     3066                        /* translators: 1: 'path', 2: filesystem path, 3: style handle */
     3067                        __( 'Unable to read the "%1$s" key with value "%2$s" for stylesheet "%3$s".' ),
     3068                        'path',
     3069                        esc_html( $style['path'] ),
     3070                        esc_html( $style['handle'] )
     3071                    ),
     3072                    '7.0.0'
     3073                );
     3074                continue;
     3075            }
    30513076            $style['css'] = file_get_contents( $style['path'] );
    30523077
  • trunk/tests/phpunit/tests/dependencies/styles.php

    r61411 r61416  
    717717    /**
    718718     * @ticket 58394
     719     * @ticket 64447
    719720     *
    720721     * @covers ::wp_maybe_inline_styles
    721      */
    722     public function test_test_wp_maybe_inline_styles_missing_file() {
     722     * @expectedIncorrectUsage wp_maybe_inline_styles
     723     */
     724    public function test_wp_maybe_inline_styles_missing_file() {
    723725        $filter = new MockAction();
    724726        add_filter( 'pre_wp_filesize', array( $filter, 'filter' ) );
     
    767769
    768770        $this->assertSame( $GLOBALS['wp_styles']->registered['test-handle']->src, $url );
     771    }
     772
     773    /**
     774     * @ticket 64447
     775     *
     776     * @covers ::wp_maybe_inline_styles
     777     * @expectedIncorrectUsage wp_maybe_inline_styles
     778     */
     779    public function test_wp_maybe_inline_styles_bad_path_with_file_size_provided() {
     780        $style_path = '/css/invalid.css'; // Does not exist.
     781
     782        // This ensures the initial file size check is bypassed.
     783        add_filter(
     784            'pre_wp_filesize',
     785            static function ( $size, $path ) use ( $style_path ) {
     786                if ( str_contains( $path, $style_path ) ) {
     787                    $size = 1000;
     788                }
     789                return $size;
     790            },
     791            10,
     792            2
     793        );
     794
     795        $handle = 'test-handle';
     796        $url    = '/' . WPINC . $style_path;
     797        wp_register_style( $handle, $url );
     798        wp_style_add_data( $handle, 'path', ABSPATH . WPINC . $style_path );
     799        wp_enqueue_style( $handle );
     800
     801        wp_maybe_inline_styles();
     802
     803        $this->assertSame( $GLOBALS['wp_styles']->registered[ $handle ]->src, $url );
     804    }
     805
     806    /**
     807     * @ticket 64447
     808     *
     809     * @covers ::wp_maybe_inline_styles
     810     */
     811    public function test_wp_maybe_inline_styles_good_path_with_zero_file_size_provided() {
     812        $style_path = '/css/classic-themes.css';
     813
     814        // This simulates the file having a zero size.
     815        add_filter(
     816            'pre_wp_filesize',
     817            static function ( $size, $path ) use ( $style_path ) {
     818                if ( str_contains( $path, $style_path ) ) {
     819                    $size = 0;
     820                }
     821                return $size;
     822            },
     823            10,
     824            2
     825        );
     826
     827        $handle = 'test-handle';
     828        wp_register_style( $handle, '/' . WPINC . $style_path );
     829        wp_style_add_data( $handle, 'path', ABSPATH . WPINC . $style_path );
     830        wp_enqueue_style( $handle );
     831
     832        wp_maybe_inline_styles();
     833
     834        $this->assertFalse( $GLOBALS['wp_styles']->registered[ $handle ]->src );
    769835    }
    770836
  • trunk/tests/phpunit/tests/media.php

    r60971 r61416  
    66786678     */
    66796679    public function test_wp_enqueue_img_auto_sizes_contain_css_fix( ?Closure $set_up, bool $expected, ?string $expected_deprecated = null ): void {
     6680        // These files are created as part of the build process, but the unit tests don't run the build prior to running unit tests on GHA.
     6681        self::touch( ABSPATH . WPINC . '/css/dist/block-library/style.css' );
     6682        self::touch( ABSPATH . WPINC . '/css/dist/block-library/common.css' );
     6683
    66806684        if ( $set_up ) {
    66816685            $set_up();
  • trunk/tests/phpunit/tests/template.php

    r61174 r61416  
    16781678     */
    16791679    public function test_wp_hoist_late_printed_styles( ?Closure $set_up, int $inline_size_limit, array $expected_styles ): void {
     1680        // `_print_emoji_detection_script()` assumes `wp-includes/js/wp-emoji-loader.js` is present:
     1681        self::touch( ABSPATH . WPINC . '/js/wp-emoji-loader.js' );
     1682
    16801683        switch_theme( 'default' );
    16811684        global $wp_styles;
     
    17121715            wp_should_load_separate_core_block_assets() ? 'css/dist/block-library/common.css' : 'css/dist/block-library/style.css'
    17131716        );
     1717        $this->ensure_style_asset_file_created( 'wp-block-library-theme', 'css/dist/block-library/theme.css' );
     1718
    17141719        if ( wp_should_load_separate_core_block_assets() ) {
    17151720            $this->ensure_style_asset_file_created( 'wp-block-separator', 'blocks/separator/style.css' );
     
    18281833        $dependency->src = includes_url( $relative_path );
    18291834        $path            = ABSPATH . WPINC . '/' . $relative_path;
    1830         if ( ! file_exists( $path ) ) {
    1831             $dir = dirname( $path );
    1832             if ( ! file_exists( $dir ) ) {
    1833                 mkdir( $dir, 0777, true );
    1834             }
     1835        self::touch( $path );
     1836        if ( 0 === filesize( $path ) ) {
    18351837            file_put_contents( $path, "/* CSS for $handle */" );
    18361838        }
Note: See TracChangeset for help on using the changeset viewer.