Skip to content

Commit b057ff2

Browse files
committed
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 WordPress#10653 Follow-up to [50836]. Props westonruter, jonsurrell, soyebsalar01. See #52620. Fixes #64447. git-svn-id: https://develop.svn.wordpress.org/trunk@61416 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 1bd29b1 commit b057ff2

File tree

4 files changed

+104
-7
lines changed

4 files changed

+104
-7
lines changed

src/wp-includes/script-loader.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3010,7 +3010,18 @@ function wp_maybe_inline_styles() {
30103010
$path = $wp_styles->get_data( $handle, 'path' );
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
}
30163027
$styles[] = array(
@@ -3048,6 +3059,20 @@ static function ( $a, $b ) {
30483059
}
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

30533078
/*

tests/phpunit/tests/dependencies/styles.php

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,10 +716,12 @@ public function test_wp_maybe_inline_styles_multiple_runs() {
716716

717717
/**
718718
* @ticket 58394
719+
* @ticket 64447
719720
*
720721
* @covers ::wp_maybe_inline_styles
722+
* @expectedIncorrectUsage wp_maybe_inline_styles
721723
*/
722-
public function test_test_wp_maybe_inline_styles_missing_file() {
724+
public function test_wp_maybe_inline_styles_missing_file() {
723725
$filter = new MockAction();
724726
add_filter( 'pre_wp_filesize', array( $filter, 'filter' ) );
725727
$url = '/' . WPINC . '/css/invalid.css';
@@ -768,6 +770,70 @@ public function test_wp_maybe_inline_styles_no_path() {
768770
$this->assertSame( $GLOBALS['wp_styles']->registered['test-handle']->src, $url );
769771
}
770772

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 );
835+
}
836+
771837
/**
772838
* @ticket 63887
773839
*/

tests/phpunit/tests/media.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6677,6 +6677,10 @@ static function () {
66776677
* @dataProvider data_provider_data_provider_to_test_wp_enqueue_img_auto_sizes_contain_css_fix
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();
66826686
}

tests/phpunit/tests/template.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1677,6 +1677,9 @@ function (): void {
16771677
* @dataProvider data_wp_hoist_late_printed_styles
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;
16821685
$wp_styles = null;
@@ -1711,6 +1714,8 @@ static function () {
17111714
'wp-block-library',
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' );
17161721
}
@@ -1827,11 +1832,8 @@ private function ensure_style_asset_file_created( string $handle, string $relati
18271832
}
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
}
18371839
wp_style_add_data( $handle, 'path', $path );

0 commit comments

Comments
 (0)