Make WordPress Core


Ignore:
Timestamp:
11/08/2021 01:23:44 PM (3 years ago)
Author:
gziolo
Message:

Fix relative URLs in inlined block styles that involve external assets

When styles got inlined, relative URLs break. The problem was that URLs inside CSS files are relative to the stylesheet's path, and when styles get inlined that relation is lost. This patch fixes the issue by finding relative URLs which then get modified to be relative to the site's root.

Fixes #54243.
Props aristath, cdyerkes, hellofromtonya.

File:
1 edited

Legend:

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

    r52032 r52036  
    27022702            $styles[] = array(
    27032703                'handle' => $handle,
     2704                'src'    => $wp_styles->registered[ $handle ]->src,
    27042705                'path'   => $wp_styles->registered[ $handle ]->extra['path'],
    27052706                'size'   => filesize( $wp_styles->registered[ $handle ]->extra['path'] ),
     
    27362737            $style['css'] = file_get_contents( $style['path'] );
    27372738
     2739            // Check if the style contains relative URLs that need to be modified.
     2740            // URLs relative to the stylesheet's path should be converted to relative to the site's root.
     2741            $style['css'] = _wp_normalize_relative_css_links( $style['css'], $style['src'] );
     2742
    27382743            // Set `src` to `false` and add styles inline.
    27392744            $wp_styles->registered[ $style['handle'] ]->src = false;
     
    27502755
    27512756/**
     2757 * Make URLs relative to the WordPress installation.
     2758 *
     2759 * @since 5.9.0
     2760 * @access private
     2761 *
     2762 * @param string $css            The CSS to make URLs relative to the WordPress installation.
     2763 * @param string $stylesheet_url The URL to the stylesheet.
     2764 *
     2765 * @return string The CSS with URLs made relative to the WordPress installation.
     2766 */
     2767function _wp_normalize_relative_css_links( $css, $stylesheet_url ) {
     2768    $has_src_results = preg_match_all( '#url\s*\(\s*[\'"]?\s*([^\'"\)]+)#', $css, $src_results );
     2769    if ( $has_src_results ) {
     2770        // Loop through the URLs to find relative ones.
     2771        foreach ( $src_results[1] as $src_index => $src_result ) {
     2772            // Skip if this is an absolute URL.
     2773            if ( 0 === strpos( $src_result, 'http' ) || 0 === strpos( $src_result, '//' ) ) {
     2774                continue;
     2775            }
     2776
     2777            // Build the absolute URL.
     2778            $absolute_url = dirname( $stylesheet_url ) . '/' . $src_result;
     2779            $absolute_url = str_replace( '/./', '/', $absolute_url );
     2780            // Convert to URL related to the site root.
     2781            $relative_url = wp_make_link_relative( $absolute_url );
     2782
     2783            // Replace the URL in the CSS.
     2784            $css = str_replace(
     2785                $src_results[0][ $src_index ],
     2786                str_replace( $src_result, $relative_url, $src_results[0][ $src_index ] ),
     2787                $css
     2788            );
     2789        }
     2790    }
     2791
     2792    return $css;
     2793}
     2794
     2795/**
    27522796 * Inject the block editor assets that need to be loaded into the editor's iframe as an inline script.
    27532797 *
Note: See TracChangeset for help on using the changeset viewer.