wp/wp-admin/load-styles.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
--- a/wp/wp-admin/load-styles.php	Thu Sep 29 08:06:27 2022 +0200
+++ b/wp/wp-admin/load-styles.php	Fri Sep 05 18:40:08 2025 +0200
@@ -48,7 +48,26 @@
 $wp_styles = new WP_Styles();
 wp_default_styles( $wp_styles );
 
-if ( isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) && stripslashes( $_SERVER['HTTP_IF_NONE_MATCH'] ) === $wp_version ) {
+$etag = "WP:{$wp_version};";
+
+foreach ( $load as $handle ) {
+	if ( ! array_key_exists( $handle, $wp_styles->registered ) ) {
+		continue;
+	}
+
+	$ver   = $wp_styles->registered[ $handle ]->ver ? $wp_styles->registered[ $handle ]->ver : $wp_version;
+	$etag .= "{$handle}:{$ver};";
+}
+
+/*
+ * This is not intended to be cryptographically secure, just a fast way to get
+ * a fixed length string based on the script versions. As this file does not
+ * load the full WordPress environment, it is not possible to use the salted
+ * wp_hash() function.
+ */
+$etag = 'W/"' . md5( $etag ) . '"';
+
+if ( isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) && stripslashes( $_SERVER['HTTP_IF_NONE_MATCH'] ) === $etag ) {
 	header( "$protocol 304 Not Modified" );
 	exit;
 }
@@ -73,7 +92,8 @@
 
 	$content = get_file( $path ) . "\n";
 
-	if ( strpos( $style->src, '/' . WPINC . '/css/' ) === 0 ) {
+	// Note: str_starts_with() is not used here, as wp-includes/compat.php is not loaded in this file.
+	if ( 0 === strpos( $style->src, '/' . WPINC . '/css/' ) ) {
 		$content = str_replace( '../images/', '../' . WPINC . '/images/', $content );
 		$content = str_replace( '../js/tinymce/', '../' . WPINC . '/js/tinymce/', $content );
 		$content = str_replace( '../fonts/', '../' . WPINC . '/fonts/', $content );
@@ -83,7 +103,7 @@
 	}
 }
 
-header( "Etag: $wp_version" );
+header( "Etag: $etag" );
 header( 'Content-Type: text/css; charset=UTF-8' );
 header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + $expires_offset ) . ' GMT' );
 header( "Cache-Control: public, max-age=$expires_offset" );