Opened 10 hours ago
Last modified 8 hours ago
#66199 new defect (bug)
Style Engine collapses significant whitespace inside quoted CSS strings
| Reported by: | kimjiwoon | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Awaiting Review |
| Component: | Editor | Version: | |
| Severity: | normal | Keywords: | has-patch has-unit-tests |
| Cc: | Focuses: | css |
Description
The Style Engine keeps a declaration's value twice: once as the value it was given, and once as the CSS it compiles. The two disagree when the value contains a run of whitespace inside a quoted string, because every value is filtered through wp_strip_all_tags( $value, true ), whose second argument replaces each run of \r, \n, \t or space with a single space.
Reproduction
A font family whose name contains two spaces, which needs nothing but core:
<?php $styles = wp_style_engine_get_styles( array( 'typography' => array( 'fontFamily' => '"My Font", sans-serif' ) ) ); $styles['declarations']['font-family']; // "My Font", sans-serif $styles['css']; // font-family:"My Font", sans-serif;
The serialized CSS no longer names exactly the family that was supplied, so it may match a different family or fall back. Nothing reports that the value was changed.
Where it happens
WP_Style_Engine_CSS_Declarations::filter_declaration():
<?php $filtered_value = wp_strip_all_tags( $value, true );
and in wp_strip_all_tags():
<?php if ( $remove_breaks ) { $text = preg_replace( '/[\r\n\t ]+/', ' ', $text ); } return trim( $text );
The helper's $remove_breaks parameter is documented as removing "left over line breaks and white space chars", so this behavior is consistent with its contract. It is unsafe for CSS values where whitespace inside a quoted string is data rather than formatting, and the Style Engine applies it to every declaration it writes.
How this came up
While adding font-variation-settings in #13789 (Trac #66198). The OpenType Design-Variation Axis Tag Registry defines an axis tag as four bytes beginning with a letter, and allows a tag with fewer than four letters or digits to be padded with trailing spaces, so "abc " and "a " are valid tags. Accepting them produced this:
value given: array( 'a ' => 12 ) declarations: font-variation-settings: "a " 12 compiled CSS: font-variation-settings: "a " 12
"a " is a different tag from "a ", so the axis is not the one that was asked for.
That pull request now refuses a padded tag. That is a limit rather than a fix: it keeps the Style Engine from writing a tag other than the one requested, and it leaves WordPress unable to carry a space-padded axis tag at all. The tags in ordinary use are four characters, so the practical cost is small, but the reason it was chosen is this ticket.
Scope
This is not specific to typography. Any CSS value whose meaning depends on repeated whitespace inside a quoted string is affected, and the family-name case above needs no new feature to reproduce.
I am not proposing a particular fix here, because the call sits on the path of every declaration the Style Engine emits: narrowing it changes output well beyond typography, and it is part of a sanitization path, so it deserves to be looked at with that in mind rather than patched from inside a feature branch.
Related: Trac #66198, wordpress-develop#13789.
Change History (2)
This ticket was mentioned in PR #13791 on WordPress/wordpress-develop by @therssoftware.
9 hours ago
#1
- Keywords has-patch has-unit-tests added
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
Trac ticket: https://core.trac.wordpress.org/ticket/66199
Description
In
WP_Style_Engine_CSS_Declarations::filter_declaration(), declarations are sanitized before being compiled into CSS rules. Previously,wp_strip_all_tags( $value, true )was called with$remove_breaks = true. Becausewp_strip_all_tags()replaces all runs of[\r\n\t ]+with a single space when$remove_breaksistrue, this aggressively collapsed consecutive spaces inside quoted strings (e.g. font family names such as"My Font", sans-serifbecame"My Font", and space-padded OpenType variation axis tags such as"a "became"a ").This PR updates
filter_declaration()to:wp_strip_all_tags( $value )without removing breaks.wpStyleEngineCssDeclarations.phpverifying whitespace preservation inside quotes and integration withwp_style_engine_get_styles().Testing Instructions
`bash vendor/bin/phpunit tests/phpunit/tests/style-engine/wpStyleEngineCssDeclarations.phpphp
$styles = wp_style_engine_get_styles(
);
Both declaration and compiled CSS now agree:
$stylesdeclarationsfont-family === '"My Font", sans-serif'
$stylescss === 'font-family:"My Font", sans-serif;'
Props therssoftware.
AI Disclosure: In accordance with the WordPress AI policy, I disclose that generative AI (Google Antigravity) was used in drafting the fix, regex string-splitting implementation, and unit tests, and all code was manually verified and tested against the full PHPUnit test suite.