[wp-trac] [WordPress Trac] #63568: WP_Font_Face: Font names that contain single quotes are not wrapped in double quotes
WordPress Trac
noreply at wordpress.org
Mon Sep 15 07:58:05 UTC 2025
#63568: WP_Font_Face: Font names that contain single quotes are not wrapped in
double quotes
-------------------------------------------------+-------------------------
Reporter: wildworks | Owner: audrasjb
Type: defect (bug) | Status: accepted
Priority: normal | Milestone: 6.9
Component: Editor | Version: 6.4
Severity: normal | Resolution:
Keywords: has-patch has-test-info has- | Focuses: ui
screenshots commit |
-------------------------------------------------+-------------------------
Comment (by jonsurrell):
I started to work on improvements to the proposed normalization function
and have some findings to share. I'm unfamiliar with the font system in
WordPress, so I may have misinterpreted or overlooked some things. In
particular, I'm not familiar with the system as a whole and am mostly
interpreting things from the CSS perspective.
-----
The linked PR touches font families in two places:
- `WP_Font_Face::build_font_face_css()`
[https://core.trac.wordpress.org/browser/tags/6.8.2/src/wp-includes/fonts
/class-wp-font-face.php#L358 (source)]
- `WP_Font_Utils::sanitize_font_family()`
[https://core.trac.wordpress.org/browser/tags/6.8.2/src/wp-includes/fonts
/class-wp-font-utils.php#L60 (source)]
I believe these serve different purposes while both dealing with `font-
family`. This is because `::build_font_face_css()` corresponds to an
`@font-face` at-rule. This `@font-family` `font-family` takes a single
value. It is [https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face
/font-family not the same] as the `font-family`
[https://developer.mozilla.org/en-US/docs/Web/CSS/font-family CSS
property] that takes a comma-separated list of values to match font-
family.
On the linked PR, [https://github.com/WordPress/wordpress-
develop/pull/8982#issuecomment-2976190329 I suggested always quoting font
names]. **That must not be applied in both places.** I believe it
''should'' be applied in `::build_font_face_css()` but not
`::sanitize_font_family()`.
-----
The main problem being addressed here is in
`WP_Font_Face::build_font_face_css()` where a simple font family string is
provided (as part of a larger `$font_face` array). This is a PHP string of
a font family name, not a CSS string.
Assuming the input is a PHP string (not an escaped or quoted CSS string)
the provided font-family name can and should be normalized. Always quoting
the value simplifies escaping and prevents collisions with generic family
names. [https://www.w3.org/TR/css-fonts-4/#family-name-syntax See the
specification.]
Normalization might look something like this:
{{{#!php
<?php
function normalize_font_family_name( string $font_family ): string {
return '"' . strtr(
trim( $font_family, " \t\r\f\n"),
array(
/*
* Normalize preprocessed whitespace.
* https://www.w3.org/TR/css-syntax-3/#input-preprocessing
*/
"\r" => '\\A ',
"\f" => '\\A ',
"\r\n" => '\\A ',
/*
* CSS unicode escaping for problematic characters.
* https://www.w3.org/TR/css-syntax-3/#escaping
*/
"\n" => '\\A ',
'\\' => '\\5C ',
',' => '\\2C ',
'"' => '\\22 ',
)
) . '"';
}
}}}
-----
The linked PR also touches `WP_Font_Utils::sanitize_font_family()`. This
function takes a string that is a **CSS font-family declaration value**.
**I recommended leaving this entire class untouched in the PR.** Handling
a single @font-face font family name and a font-family declaration value
have different considerations and should not be conflated.
It splits a `font-family` description at `,`, applies some functions
(including normalization) to the parts, then joins the parts again with `,
`.
The applied functions are `sanitize_text_field` (which is filterable) and
possibly `::maybe_add_quotes()` renamed to
`::normalize_css_font_family_name()` in the linked PR.
The sanitization function works on some expected inputs but will break
some other valid inputs. Unfortunately, without some basic CSS parsing
it's difficult to improve. Notably, the `,` character could be part of the
CSS font name, in which case the sanitization will mangle the intended
result. I doubt that most common font-family names use `,` in the name
because it complicates use in CSS, so maybe we can ignore this point for
now.
Quoting in this sanitization function cannot be done indiscriminately.
Quotes ''must not be applied to generic font family names'' like `sans-
serif` or they will not be treated as generic families.
This function is problematic in edge cases, but I think it's best left
alone until we're prepared to implement some improved parsing.
[https://github.com/WordPress/wordpress-develop/pull/7857 HTML API: Add
CSS selector support #7857] may be helpful if folks are interested.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/63568#comment:35>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list