﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	severity	resolution	keywords	cc	focuses
66199	Style Engine collapses significant whitespace inside quoted CSS strings	kimjiwoon		"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
<?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
<?php
$filtered_value = wp_strip_all_tags( $value, true );
}}}

and in `wp_strip_all_tags()`:

{{{#!php
<?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 [https://github.com/WordPress/wordpress-develop/pull/13789 #13789] (Trac #66198). The [https://learn.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg 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, [https://github.com/WordPress/wordpress-develop/pull/13789 wordpress-develop#13789]."	defect (bug)	new	normal	Awaiting Review	Editor		normal		has-patch has-unit-tests		css
