Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
1174 commits
Select commit Hold shift + click to select a range
9332682
Merge REST plugin theme controller fuzz coverage
sirreal Jun 30, 2026
9f1d3f3
Add bounded Site Health debug data fuzzing
sirreal Jun 30, 2026
70ccc25
Update Site Health debug fuzz tracking
sirreal Jun 30, 2026
be694ae
Merge Site Health debug data fuzz coverage
sirreal Jun 30, 2026
4de5850
Add deterministic markup do_blocks fuzzing
sirreal Jun 30, 2026
6c37e7f
Update markup do_blocks fuzz tracking
sirreal Jun 30, 2026
2ba794a
Merge markup do_blocks fuzz coverage
sirreal Jun 30, 2026
5568f58
Add user preference request handler fuzzing
sirreal Jun 30, 2026
4fe8d1c
Update user preference request handler fuzz tracking
sirreal Jun 30, 2026
73e85bc
Merge user preference request handler fuzz coverage
sirreal Jun 30, 2026
10cb72a
Add admin workflow AJAX format wrapper fuzzing
sirreal Jun 30, 2026
917097d
Update admin workflow AJAX fuzz tracking
sirreal Jun 30, 2026
78852cd
Merge admin workflow AJAX format fuzz coverage
sirreal Jun 30, 2026
6842708
Add admin dashboard setup fuzz coverage
sirreal Jun 30, 2026
ff4064a
Update component fuzz dashboard for admin dashboard setup
sirreal Jun 30, 2026
9c5d127
Merge admin dashboard setup fuzz coverage
sirreal Jun 30, 2026
bc2dec6
Add classic nav menu helper fuzz coverage
sirreal Jun 30, 2026
52c162f
Update component fuzz dashboard for classic nav helpers
sirreal Jun 30, 2026
f41b97c
Merge classic nav menu helper fuzz coverage
sirreal Jun 30, 2026
a3c1660
Add revision template fuzz coverage
sirreal Jun 30, 2026
b107d4d
Update component fuzz dashboard for revision templates
sirreal Jun 30, 2026
aee631c
Merge revision template fuzz coverage
sirreal Jun 30, 2026
bc27826
Add global stylesheet fuzz coverage
sirreal Jun 30, 2026
7f66213
Update component fuzz dashboard for global stylesheet coverage
sirreal Jun 30, 2026
4c2a567
Merge style global stylesheet fuzz coverage
sirreal Jun 30, 2026
152c90d
Add bounded REST template controller fuzz coverage
sirreal Jun 30, 2026
d5c0747
Update component fuzz dashboard for REST template controllers
sirreal Jun 30, 2026
2435189
Merge REST template controller fuzz coverage
sirreal Jun 30, 2026
91a7645
Add appearance media admin guard fuzz coverage
sirreal Jun 30, 2026
ae39138
Update component fuzz dashboard for appearance media guards
sirreal Jun 30, 2026
4999143
Merge appearance media admin guard fuzz coverage
sirreal Jun 30, 2026
0b57a42
Add REST site editor template dispatch guards
sirreal Jun 30, 2026
1be91fa
Update component fuzz dashboard for REST site editor guards
sirreal Jun 30, 2026
ee35074
Merge REST site editor template dispatch guards
sirreal Jun 30, 2026
6a28aff
Retire stale admin list table privacy skip
sirreal Jun 30, 2026
3b77b01
Update component fuzz dashboard for admin list privacy accounting
sirreal Jun 30, 2026
350f1ef
Merge admin list privacy accounting
sirreal Jun 30, 2026
b59b503
Retire stale admin workflow list table skip
sirreal Jun 30, 2026
81ed3d9
Update component fuzz dashboard for admin workflow list accounting
sirreal Jun 30, 2026
366fc2c
Merge admin workflow list accounting
sirreal Jun 30, 2026
d4a516e
Split script loader emoji style coverage
sirreal Jun 30, 2026
707ec85
Update component fuzz dashboard for script loader emoji split
sirreal Jun 30, 2026
3c6c08f
Merge script loader emoji style split
sirreal Jun 30, 2026
d9f3bf8
Retire REST object collection query skip
sirreal Jun 30, 2026
20b8de8
Update component fuzz dashboard for REST query skip retirement
sirreal Jun 30, 2026
2566fb4
Merge REST object query skip retirement
sirreal Jun 30, 2026
a8de6a7
Retire metadata subtype helper availability skip
sirreal Jun 30, 2026
f4276c2
Update component fuzz dashboard for metadata subtype accounting
sirreal Jun 30, 2026
782e0be
Merge metadata subtype accounting
sirreal Jun 30, 2026
98c2346
Retire WXR export header observability skip
sirreal Jun 30, 2026
2f5e0f1
Update component fuzz dashboard for WXR header accounting
sirreal Jun 30, 2026
97b5036
Merge WXR header accounting
sirreal Jun 30, 2026
12d7260
Retire admin media chrome boundary skips
sirreal Jun 30, 2026
86c9c38
Update component fuzz dashboard for admin media boundaries
sirreal Jun 30, 2026
76ea774
Merge admin media boundary accounting
sirreal Jun 30, 2026
791c426
Retire site health database malformed-row skip
sirreal Jun 30, 2026
ec614aa
Update component fuzz dashboard for site health database boundary
sirreal Jun 30, 2026
783f931
Merge site health database boundary accounting
sirreal Jun 30, 2026
8fd73af
Retire media editor availability skip
sirreal Jun 30, 2026
21ba29b
Update component fuzz dashboard for media editor availability
sirreal Jun 30, 2026
28a661d
Merge media editor availability accounting
sirreal Jun 30, 2026
e52e60e
Retire script loader emoji asset skip
sirreal Jun 30, 2026
f0c259d
Update component fuzz dashboard for script loader emoji asset
sirreal Jun 30, 2026
c64056c
Merge script loader emoji asset accounting
sirreal Jun 30, 2026
61e22a3
Expand error protection pure boundary coverage
sirreal Jun 30, 2026
9a65e8d
Update component fuzz dashboard for error protection boundaries
sirreal Jun 30, 2026
a90fb2d
Merge error protection pure boundary coverage
sirreal Jun 30, 2026
e581555
Expand REST directory service fuzz oracles
sirreal Jun 30, 2026
ba8c823
Update component fuzz dashboard for REST directory services
sirreal Jun 30, 2026
514296b
Merge REST directory service fuzz oracles
sirreal Jun 30, 2026
ece71f4
Expand network media upload bits fuzz coverage
sirreal Jun 30, 2026
edb95f6
Update component fuzz dashboard for network media upload bits
sirreal Jun 30, 2026
19c5b11
Merge network media upload bits fuzz coverage
sirreal Jun 30, 2026
ec3e228
Expand shortcode HTML attribute fuzz coverage
sirreal Jun 30, 2026
cc25151
Update component fuzz dashboard for shortcode HTML attributes
sirreal Jun 30, 2026
0d112ea
Merge shortcode HTML attribute fuzz coverage
sirreal Jun 30, 2026
764df53
Expand security fuzz coverage
sirreal Jun 30, 2026
42a15d1
Update security fuzz dashboard
sirreal Jun 30, 2026
4edaea7
Merge security referer and password fuzz coverage
sirreal Jun 30, 2026
6a78c3e
Expand post embeds consumer fuzz coverage
sirreal Jun 30, 2026
803f276
Update post embeds fuzz dashboard
sirreal Jun 30, 2026
730694d
Merge post embeds consumer fuzz coverage
sirreal Jun 30, 2026
63a3441
Add REST application password auth status fuzzing
sirreal Jun 30, 2026
0af115c
Merge REST application password status fuzz coverage
sirreal Jun 30, 2026
a85bf29
Add import upload lifecycle fuzzing
sirreal Jun 30, 2026
dc326eb
Merge import upload lifecycle fuzz coverage
sirreal Jun 30, 2026
663ad13
Add admin email options fuzzing
sirreal Jun 30, 2026
53a3127
Merge admin email options fuzz coverage
sirreal Jun 30, 2026
3344023
Add privacy request resend fuzzing
sirreal Jun 30, 2026
b24bb44
Merge privacy request resend fuzz coverage
sirreal Jun 30, 2026
eb24078
Add REST media sideload fuzzing
sirreal Jun 30, 2026
59f7858
Merge REST media sideload fuzz coverage
sirreal Jun 30, 2026
51f1479
Add REST plugin write fuzzing
sirreal Jun 30, 2026
116b329
Merge REST plugin write fuzz coverage
sirreal Jun 30, 2026
b081ba8
Add Customizer save AJAX fuzzing
sirreal Jun 30, 2026
9c623b8
Merge Customizer save AJAX fuzz coverage
sirreal Jun 30, 2026
02b97a3
Add Site Editor template mutation fuzzing
sirreal Jun 30, 2026
1ca8ebe
Merge Site Editor template mutation fuzz coverage
sirreal Jun 30, 2026
6d0b0c5
Add REST block pattern loader fuzzing
sirreal Jun 30, 2026
2a53478
Merge REST block pattern loader fuzz coverage
sirreal Jun 30, 2026
8f7e047
Add REST block pattern file fuzzing
sirreal Jun 30, 2026
2a8c2dd
Merge REST block pattern file fuzz coverage
sirreal Jun 30, 2026
9500618
Add repeat-safe theme install list table replay
sirreal Jun 30, 2026
1c7ac6a
Merge admin theme install replay fuzz coverage
sirreal Jun 30, 2026
2f803af
Add privacy admin action fuzz coverage
sirreal Jun 30, 2026
5976935
Merge privacy admin action fuzz coverage
sirreal Jun 30, 2026
dd06e9a
Add XML-RPC write method fuzz coverage
sirreal Jun 30, 2026
e578211
Merge XML-RPC write method fuzz coverage
sirreal Jun 30, 2026
1826986
Add WXR export edge-case fuzz coverage
sirreal Jun 30, 2026
3e97e14
Merge WXR export edge-case fuzz coverage
sirreal Jun 30, 2026
d689acc
Add updater notification fuzz coverage
sirreal Jun 30, 2026
ad65597
Merge updater notification fuzz coverage
sirreal Jun 30, 2026
a317355
Add feed parser RDF and fetch_feed fuzz coverage
sirreal Jun 30, 2026
63e1073
Merge feed parser RDF and fetch_feed fuzz coverage
sirreal Jun 30, 2026
e173e3b
Fix token map export fuzz coverage
sirreal Jun 30, 2026
78fe051
Merge token map export fuzz coverage
sirreal Jun 30, 2026
35cb2b4
Add community events AJAX fuzz coverage
sirreal Jun 30, 2026
dbfbfde
Merge community events AJAX fuzz coverage
sirreal Jun 30, 2026
edd517d
Add core navigation render fuzz coverage
sirreal Jun 30, 2026
5ff01b2
Merge core navigation render fuzz coverage
sirreal Jun 30, 2026
372710e
Add admin list table subclass fuzz coverage
sirreal Jul 1, 2026
fdb372c
Merge admin list table subclass fuzz coverage
sirreal Jul 1, 2026
d023f7f
Add error protection process-control fuzz coverage
sirreal Jul 1, 2026
ee5f264
Merge error protection process-control fuzz coverage
sirreal Jul 1, 2026
2d5b698
Add REST plugin install lifecycle fuzz coverage
sirreal Jul 1, 2026
9c5a7cb
Merge REST plugin install lifecycle fuzz coverage
sirreal Jul 1, 2026
33b352d
Add REST meta field component fuzz coverage
sirreal Jul 1, 2026
681b6d5
Merge REST meta field fuzz coverage
sirreal Jul 1, 2026
8aafd7a
Add core block frontend list fuzz coverage
sirreal Jul 1, 2026
643ba2f
Add appearance media head callback fuzzing
sirreal Jul 1, 2026
81d2a1b
Update dashboard for appearance media callbacks
sirreal Jul 1, 2026
a942ff5
Add site icon attachment URL fuzzing
sirreal Jul 1, 2026
0541b41
Update dashboard for site icon attachment fuzzing
sirreal Jul 1, 2026
627a726
Add custom header print side effect fuzzing
sirreal Jul 1, 2026
f738533
Update dashboard for custom header print fuzzing
sirreal Jul 1, 2026
87b8fc9
Add REST directory block field fuzzing
sirreal Jul 1, 2026
2030575
Update dashboard for REST directory block fuzzing
sirreal Jul 1, 2026
6070f5e
Add admin ajax find posts fuzzing
sirreal Jul 1, 2026
3630957
Update dashboard for admin ajax find posts fuzzing
sirreal Jul 1, 2026
753d2b2
Add classic nav menu query fuzzing
sirreal Jul 1, 2026
a936324
Escape application password last IP output
sirreal Jul 1, 2026
4903e58
Guard block template direct IDs
sirreal Jul 1, 2026
72dcdc8
Support punycode TLD mailto links
sirreal Jul 1, 2026
dae0656
Add image metadata fixture replay fuzzing
sirreal Jul 1, 2026
4675414
Add block supports duotone fuzzing
sirreal Jul 1, 2026
86ea8e8
Add formatting file and user sanitizer fuzzing
sirreal Jul 1, 2026
5f70f48
Add post status viewability fuzzing
sirreal Jul 1, 2026
62b1003
Add canonical attachment redirect fuzzing
sirreal Jul 1, 2026
55126a6
Add revisions preview dispatch fuzzing
sirreal Jul 1, 2026
0a9369f
Add appearance background remove fuzzing
sirreal Jul 1, 2026
70a53bc
Add template post class fuzzing
sirreal Jul 1, 2026
3a9087b
Add request send headers exit fuzzing
sirreal Jul 1, 2026
56d504b
Add canonical old slug date fuzzing
sirreal Jul 1, 2026
549a465
Add KSES hair parser fixture fuzzing
sirreal Jul 1, 2026
c6f44a8
Add feed enclosure fixture fuzzing
sirreal Jul 1, 2026
d6eab04
Add admin notice fixture fuzzing
sirreal Jul 1, 2026
7eaef5f
Add adjacent image link fuzzing
sirreal Jul 1, 2026
08c10c3
Add REST block renderer fuzzing
sirreal Jul 1, 2026
2aa549b
Add REST menu location fuzzing
sirreal Jul 1, 2026
1c50be9
Add sitemap stylesheet fuzzing
sirreal Jul 1, 2026
b4ebfa3
Add rewrite url_to_postid fuzzing
sirreal Jul 1, 2026
11ae4a9
Add wptexturize formatting fuzzing
sirreal Jul 1, 2026
66f789d
Add REST Site Editor collection dispatch fuzzing
sirreal Jul 1, 2026
c6ad69c
Add filesystem archive and move fuzzing
sirreal Jul 1, 2026
36193e5
Add privacy export ZIP fuzzing
sirreal Jul 1, 2026
1b43ba0
Add mail address header encoding fuzzing
sirreal Jul 1, 2026
9c80532
Add REST app password response fuzzing
sirreal Jul 1, 2026
f6967e5
Add comment notification mail fuzzing
sirreal Jul 1, 2026
bdd0739
Add block hooks post object fuzz coverage
sirreal Jul 1, 2026
5c292a5
Add post count MIME helper fuzz coverage
sirreal Jul 1, 2026
ba6ab39
Add post thumbnail helper fuzz coverage
sirreal Jul 1, 2026
d7893f7
Add utility internals helper fuzz coverage
sirreal Jul 1, 2026
37f6f51
Add environment memory limit fuzz coverage
sirreal Jul 1, 2026
92cc125
Add diagnostic error helper fuzz coverage
sirreal Jul 1, 2026
408aa19
Add block bindings registry fuzz coverage
sirreal Jul 1, 2026
9cc3edd
Add dashboard community events fuzz coverage
sirreal Jul 1, 2026
6056b78
Add set post type fuzz coverage
sirreal Jul 1, 2026
4900c9b
Add navigation fallback fuzz coverage
sirreal Jul 1, 2026
c915462
Add robots.txt front controller fuzz coverage
sirreal Jul 1, 2026
4029ff5
Update discovery validation ledger
sirreal Jul 1, 2026
cd5fe64
Add global styles user data fuzz coverage
sirreal Jul 1, 2026
0d80005
Update style validation ledger
sirreal Jul 1, 2026
474524f
Add favicon front-controller discovery fuzz coverage
sirreal Jul 1, 2026
da31184
Update favicon discovery validation ledger
sirreal Jul 1, 2026
23df3bb
Add state cache blog switch fuzz coverage
sirreal Jul 1, 2026
b847845
Update state cache validation ledger
sirreal Jul 1, 2026
f49c489
Add hierarchical taxonomy term link fuzz coverage
sirreal Jul 1, 2026
6f61e40
Update taxonomy term link validation ledger
sirreal Jul 1, 2026
925224f
Add admin options core page fuzz coverage
sirreal Jul 1, 2026
1905a76
Update admin options validation ledger
sirreal Jul 1, 2026
6afe48a
Add Customizer theme preview fuzz coverage
sirreal Jul 1, 2026
0139faf
Update Customizer theme preview validation ledger
sirreal Jul 1, 2026
69ffaf4
Add auth logout fuzz coverage
sirreal Jul 1, 2026
537b1e9
Update auth logout validation ledger
sirreal Jul 1, 2026
de1da7b
Add cron wrapper fuzz coverage
sirreal Jul 1, 2026
3606d54
Update cron wrapper validation ledger
sirreal Jul 1, 2026
5a6cad2
Add auth login form fuzz coverage
sirreal Jul 1, 2026
427f74f
Update auth login form validation ledger
sirreal Jul 1, 2026
903654a
Add search form fuzz coverage
sirreal Jul 1, 2026
7d9cfcc
Update search form validation ledger
sirreal Jul 1, 2026
6195e53
Add media shortcode fuzz coverage
sirreal Jul 1, 2026
a43c7b4
Update media shortcode validation ledger
sirreal Jul 1, 2026
ead9a7c
Add timezone choice fuzz coverage
sirreal Jul 1, 2026
53f8f3f
Update timezone choice validation ledger
sirreal Jul 1, 2026
d10d0fa
Add option group cache priming fuzz coverage
sirreal Jul 1, 2026
f4039ec
Update option group priming validation ledger
sirreal Jul 1, 2026
94c539d
Add REST batch v1 fuzz coverage
sirreal Jul 1, 2026
0283f6c
Update REST batch validation ledger
sirreal Jul 1, 2026
78b8b78
Add TinyMCE inline editor helper fuzz coverage
sirreal Jul 1, 2026
8b1eb56
Update TinyMCE inline fuzz validation ledger
sirreal Jul 1, 2026
9bfd3cd
Add comment form fuzz coverage
sirreal Jul 1, 2026
091a5ec
Update comment form fuzz validation ledger
sirreal Jul 1, 2026
5883479
Add deep formatting helper fuzz coverage
sirreal Jul 1, 2026
2052988
Update deep formatting fuzz validation ledger
sirreal Jul 1, 2026
07ddf2b
Add multisite signup validation fuzz coverage
sirreal Jul 1, 2026
9982a4a
Update multisite signup fuzz validation ledger
sirreal Jul 1, 2026
a25a6c0
Add HTTP origin helper fuzz coverage
sirreal Jul 1, 2026
c9e8966
Update HTTP origin fuzz validation ledger
sirreal Jul 1, 2026
86ea9ec
Add HTTP encoding helper fuzz coverage
sirreal Jul 1, 2026
ef731e5
Update HTTP encoding fuzz validation ledger
sirreal Jul 1, 2026
fb60b38
Add template link archive navigation fuzz coverage
sirreal Jul 1, 2026
d48cefe
Update template link archive navigation ledger
sirreal Jul 1, 2026
57fe546
Add post embed host script gate fuzz coverage
sirreal Jul 1, 2026
7e6571c
Update post embed host script fuzz ledger
sirreal Jul 1, 2026
9211f6d
Add single-site admin bar callback fuzz coverage
sirreal Jul 1, 2026
69fee16
Update admin bar callback fuzz ledger
sirreal Jul 1, 2026
07a8731
Add comments navigation helper fuzz coverage
sirreal Jul 1, 2026
cc09202
Update comments navigation fuzz ledger
sirreal Jul 1, 2026
9f14ccc
Add page lookup helper fuzz coverage
sirreal Jul 1, 2026
bf29010
Update page lookup fuzz ledger
sirreal Jul 1, 2026
309a336
Add widget editor dependency fuzz coverage
sirreal Jul 1, 2026
6c3b4ce
Update widget editor dependency fuzz ledger
sirreal Jul 1, 2026
02a4952
Add author template helper fuzz coverage
sirreal Jul 1, 2026
650edf5
Update author template fuzz ledger
sirreal Jul 1, 2026
3c10935
Add editor link query fuzz coverage
sirreal Jul 1, 2026
c952bf2
Update editor link query fuzz ledger
sirreal Jul 1, 2026
49115fa
Add built-in block binding fuzz coverage
sirreal Jul 1, 2026
f72e6a3
Add REST site editor revision collection fuzz coverage
sirreal Jul 1, 2026
feef5ba
Merge REST site editor revision collection fuzz coverage
sirreal Jul 1, 2026
32add92
Add REST built-in search handler fuzz coverage
sirreal Jul 1, 2026
cd21f2e
Merge REST built-in search handler fuzz coverage
sirreal Jul 1, 2026
b093964
Add script polyfill generation fuzz coverage
sirreal Jul 1, 2026
758e0ff
Merge script polyfill generation fuzz coverage
sirreal Jul 1, 2026
a893f3d
Add media gallery playlist fuzz coverage
sirreal Jul 1, 2026
7589c5d
Merge media gallery playlist fuzz coverage
sirreal Jul 1, 2026
c8e978a
Add wp_list_comments fuzz coverage
sirreal Jul 1, 2026
beed908
Merge wp_list_comments fuzz coverage
sirreal Jul 1, 2026
07e242d
Add admin nonce failure fuzz coverage
sirreal Jul 10, 2026
ef8e7a5
Merge admin nonce failure fuzz coverage
sirreal Jul 10, 2026
708918f
Merge branch 'trunk' into component-fuzzers
sirreal Jul 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public function column_last_ip( $item ) {
if ( empty( $item['last_ip'] ) ) {
echo '—';
} else {
echo $item['last_ip'];
echo esc_html( $item['last_ip'] );
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ private function create_psr_response( array $wp_response ): ResponseInterface {
}
}

if ( ! empty( $body ) ) {
if ( '' !== $body ) {
$stream = $this->stream_factory->createStream( $body );
$response = $response->withBody( $stream );
}
Expand Down
14 changes: 12 additions & 2 deletions src/wp-includes/block-template-utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,18 @@ function _get_block_template_file( $template_type, $slug ) {
);
foreach ( $themes as $theme_slug => $theme_dir ) {
$template_base_paths = get_block_theme_folders( $theme_slug );
$file_path = $theme_dir . '/' . $template_base_paths[ $template_type ] . '/' . $slug . '.html';
if ( file_exists( $file_path ) ) {
$template_base_path = $theme_dir . '/' . $template_base_paths[ $template_type ];
$file_path = $template_base_path . '/' . $slug . '.html';
$real_base_path = realpath( $template_base_path );
$real_file_path = realpath( $file_path );
if (
false !== $real_base_path &&
false !== $real_file_path &&
str_starts_with(
wp_normalize_path( $real_file_path ),
trailingslashit( wp_normalize_path( $real_base_path ) )
)
) {
$new_template_item = array(
'slug' => $slug,
'path' => $file_path,
Expand Down
77 changes: 70 additions & 7 deletions src/wp-includes/class-wp-block-metadata-registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class WP_Block_Metadata_Registry {
* @return bool True if the collection was registered successfully, false otherwise.
*/
public static function register_collection( $path, $manifest ) {
$path = rtrim( wp_normalize_path( $path ), '/' );
$path = self::normalize_collection_path( $path );

$collection_roots = self::get_default_collection_roots();

Expand Down Expand Up @@ -112,7 +112,7 @@ public static function register_collection( $path, $manifest ) {
$collection_roots = array_unique(
array_map(
static function ( $allowed_root ) {
return rtrim( wp_normalize_path( $allowed_root ), '/' );
return self::normalize_collection_path( $allowed_root );
},
$collection_roots
)
Expand Down Expand Up @@ -161,7 +161,7 @@ static function ( $allowed_root ) {
* @return array|null The block metadata for the block, or null if not found.
*/
public static function get_metadata( $file_or_folder ) {
$file_or_folder = wp_normalize_path( $file_or_folder );
$file_or_folder = self::normalize_collection_path( $file_or_folder );

$path = self::find_collection_path( $file_or_folder );
if ( ! $path ) {
Expand Down Expand Up @@ -196,7 +196,7 @@ public static function get_metadata( $file_or_folder ) {
* @return string[] List of block metadata file paths, or an empty array if the given `$path` is invalid.
*/
public static function get_collection_block_metadata_files( $path ) {
$path = rtrim( wp_normalize_path( $path ), '/' );
$path = self::normalize_collection_path( $path );

if ( ! isset( self::$collections[ $path ] ) ) {
_doing_it_wrong(
Expand All @@ -223,6 +223,56 @@ static function ( $block_name ) use ( $path ) {
);
}

/**
* Normalizes a collection path and collapses dot segments.
*
* @since 7.1.0
*
* @param string $path File or directory path.
* @return string Normalized path without trailing slashes.
*/
private static function normalize_collection_path( $path ) {
$path = wp_normalize_path( $path );

$prefix = '';
if ( preg_match( '#^([A-Za-z][A-Za-z0-9+.-]*://)(.*)$#', $path, $matches ) ) {
$prefix = $matches[1];
$path = $matches[2];
} elseif ( str_starts_with( $path, '//' ) ) {
$prefix = '//';
$path = substr( $path, 2 );
}

$drive = '';
if ( preg_match( '#^[A-Za-z]:#', $path, $matches ) ) {
$drive = $matches[0];
$path = substr( $path, 2 );
}

$is_absolute = str_starts_with( $path, '/' );
$parts = array();

foreach ( explode( '/', $path ) as $part ) {
if ( '' === $part || '.' === $part ) {
continue;
}
if ( '..' === $part ) {
if ( array() !== $parts && '..' !== end( $parts ) ) {
array_pop( $parts );
continue;
}
if ( ! $is_absolute ) {
$parts[] = $part;
}
continue;
}
$parts[] = $part;
}

$normalized = ( $is_absolute ? '/' : '' ) . implode( '/', $parts );
return $prefix . rtrim( $drive . $normalized, '/' );
}

/**
* Finds the collection path for a given file or folder.
*
Expand All @@ -238,20 +288,33 @@ private static function find_collection_path( $file_or_folder ) {

// Check the last matched collection first, since block registration usually happens in batches per plugin or theme.
$path = rtrim( $file_or_folder, '/' );
if ( self::$last_matched_collection && str_starts_with( $path, self::$last_matched_collection ) ) {
if ( self::$last_matched_collection && self::is_same_or_child_path( $path, self::$last_matched_collection ) ) {
return self::$last_matched_collection;
}

$collection_paths = array_keys( self::$collections );
foreach ( $collection_paths as $collection_path ) {
if ( str_starts_with( $path, $collection_path ) ) {
if ( self::is_same_or_child_path( $path, $collection_path ) ) {
self::$last_matched_collection = $collection_path;
return $collection_path;
}
}
return null;
}

/**
* Checks whether a path is equal to or inside another path.
*
* @since 7.1.0
*
* @param string $path Normalized path.
* @param string $base_path Normalized base path.
* @return bool True if the path is the base path or a child path, false otherwise.
*/
private static function is_same_or_child_path( $path, $base_path ) {
return $path === $base_path || str_starts_with( $path, $base_path . '/' );
}

/**
* Checks if metadata exists for a given block name in a specific collection.
*
Expand Down Expand Up @@ -317,7 +380,7 @@ private static function is_valid_collection_path( $path, $collection_roots ) {
}

// If the path is a parent path of any of the roots, it is invalid.
if ( str_starts_with( $allowed_root, $path ) ) {
if ( self::is_same_or_child_path( $allowed_root, $path ) ) {
return false;
}
}
Expand Down
34 changes: 23 additions & 11 deletions src/wp-includes/class-wp-email-address.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
*
* Example:
*
* $email = WP_Email_Address::from_string( 'wordpress@wordpress.org' );
* 'wordpress' === $email->get_local_part();
* 'wordpress.org' === $email->get_domain();
* $email = WP_Email_Address::from_string( 'user@example.org' );
* 'user' === $email->get_local_part();
* 'example.org' === $email->get_domain();
*
* @see self::from_string() to parse and validate a provided email address.
* @see self::get_localpart() for the local part or mailbox of the address.
Expand Down Expand Up @@ -288,19 +288,31 @@ public static function from_string( string $input, string $character_set = 'unic
}
}

// The domain must contain at least one dot.
if ( ! str_contains( $ascii_domain, '.' ) ) {
/** This filter is documented in wp-includes/formatting.php */
if ( ! apply_filters( 'is_email', false, $input, 'domain_no_periods' ) ) {
return null;
}
}

// Validate the domain against the allowed structure.
if ( 1 !== preg_match( $domain_pattern, $decoded_domain ) ) {
return null;
}

if ( $allow_unicode && 1 === preg_match( '/[\x80-\xff]/', $decoded_domain ) ) {
if ( ! function_exists( 'idn_to_ascii' ) ) {
return null;
}

$encoded_labels = array();
foreach ( explode( '.', $decoded_domain ) as $label ) {
$encoded_label = 1 === preg_match( '/[\x80-\xff]/', $label )
? idn_to_ascii( $label, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46 )
: $label;

if ( false === $encoded_label || strlen( $encoded_label ) > 63 ) {
return null;
}

$encoded_labels[] = $encoded_label;
}
$ascii_domain = implode( '.', $encoded_labels );
}

return new self( $localpart, $ascii_domain, $decoded_domain );
}

Expand Down
2 changes: 2 additions & 0 deletions src/wp-includes/class-wp-icons-registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ protected function register( $icon_name, $icon_properties ) {
);
return false;
}

$icon_properties['content'] = $sanitized_icon_content;
}

$icon = array_merge(
Expand Down
2 changes: 1 addition & 1 deletion src/wp-includes/class-wp-token-map.php
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ public function to_array(): array {
}

foreach ( $this->large_words as $index => $group ) {
$prefix = substr( $this->groups, $index * ( $this->key_length + 1 ), 2 );
$prefix = substr( $this->groups, $index * ( $this->key_length + 1 ), $this->key_length );
$group_length = strlen( $group );
$at = 0;
while ( $at < $group_length ) {
Expand Down
19 changes: 19 additions & 0 deletions src/wp-includes/class-wp-user.php
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,27 @@ public static function get_data_by( $field, $value ) {
}
}

if ( 'email' === $field ) {
$users = $wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM $wpdb->users WHERE user_email = %s",
$value
)
);

foreach ( $users as $user ) {
if ( 0 === strcasecmp( $user->user_email, $value ) ) {
update_user_caches( $user );
return $user;
}
}

return false;
}

$user = $wpdb->get_row(
$wpdb->prepare(
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- The column name is selected by the hardcoded switch above.
"SELECT * FROM $wpdb->users WHERE $db_field = %s LIMIT 1",
$value
)
Expand Down
79 changes: 69 additions & 10 deletions src/wp-includes/fonts/class-wp-font-face.php
Original file line number Diff line number Diff line change
Expand Up @@ -311,13 +311,7 @@ private function build_font_face_css( array $font_face ) {
* Wrap font-family in quotes if it contains spaces
* and is not already wrapped in quotes.
*/
if (
str_contains( $font_face['font-family'], ' ' ) &&
! str_contains( $font_face['font-family'], '"' ) &&
! str_contains( $font_face['font-family'], "'" )
) {
$font_face['font-family'] = '"' . $font_face['font-family'] . '"';
}
$font_face['font-family'] = $this->compile_font_family( $font_face['font-family'] );

foreach ( $font_face as $key => $value ) {
// Compile the "src" parameter.
Expand All @@ -338,6 +332,47 @@ private function build_font_face_css( array $font_face ) {
return $css;
}

/**
* Compiles the `font-family` into valid CSS.
*
* @since 6.4.0
*
* @param string $value Value to process.
* @return string The CSS.
*/
private function compile_font_family( $value ) {
if ( $this->font_family_needs_quotes( $value ) ) {
return '"' . $this->escape_css_string( $value, '"' ) . '"';
}

return $value;
}

/**
* Checks whether a font family value should be quoted.
*
* @since 6.4.0
*
* @param string $value Value to process.
* @return bool Whether the font family value should be quoted.
*/
private function font_family_needs_quotes( $value ) {
if (
str_contains( $value, ';' ) ||
str_contains( $value, '{' ) ||
str_contains( $value, '}' ) ||
str_contains( $value, '/*' ) ||
str_contains( $value, '*/' ) ||
preg_match( '/[\x00-\x1F\x7F]/', $value )
) {
return true;
}

return str_contains( $value, ' ' ) &&
! str_contains( $value, '"' ) &&
! str_contains( $value, "'" );
}

/**
* Compiles the `src` into valid CSS.
*
Expand All @@ -350,15 +385,39 @@ private function compile_src( array $value ) {
$src = '';

foreach ( $value as $item ) {
$src .= ( 'data' === $item['format'] )
? ", url({$item['url']})"
: ", url('{$item['url']}') format('{$item['format']}')";
$src .= ", url('" . $this->escape_css_string( $item['url'], "'" ) . "')";

if ( 'data' !== $item['format'] ) {
$src .= " format('" . $this->escape_css_string( $item['format'], "'" ) . "')";
}
}

$src = ltrim( $src, ', ' );
return $src;
}

/**
* Escapes a value for use in a quoted CSS string.
*
* @since 6.4.0
*
* @param string $value Value to process.
* @param string $quote Quote character wrapping the CSS string.
* @return string Escaped CSS string content.
*/
private function escape_css_string( $value, $quote ) {
$value = str_replace( '\\', '\\\\', $value );
$value = str_replace( $quote, '\\' . $quote, $value );

return preg_replace_callback(
'/[\x00-\x1F\x7F]/',
static function ( $matches ) {
return '\\' . strtoupper( dechex( ord( $matches[0] ) ) ) . ' ';
},
$value
);
}

/**
* Compiles the font variation settings.
*
Expand Down
Loading
Loading