Summary
Since the 2.0 rewrite, opening any page in the Oxygen Builder never finishes loading — the loading screen stays up forever. Root cause: elegant_custom_fonts() now echoes the font list into Oxygen's ct_builder_ng_init hook without HTML-escaping it, and that hook renders inside the double-quoted ng-init HTML attribute of the builder template. The first raw " from the JSON terminates the attribute mid-expression.
Affected surface
Oxygen (WordPress plugin)
Steps to reproduce
- WordPress + Oxygen Builder 4.9.7 + Core Framework 2.0.1, with at least one font in the active preset's FONTS module (e.g. ABeeZee, IBM Plex Sans).
- Open any page in the Oxygen Builder.
Expected behavior
Builder loads; elegantCustomFonts is populated with the preset fonts (as in 1.10.4).
Actual behavior
Builder hangs on the loading screen forever. Browser console shows AngularJS Error: [$parse:ueoe] (unexpected end of expression) for the builder's ng-init expression, which ends abruptly at ...init();elegantCustomFonts=[.
The served HTML contains raw quotes inside the double-quoted attribute:
ng-init="...;init();elegantCustomFonts=["ABeeZee","IBM Plex Sans"];"
so the attribute closes after [, the rest becomes garbage attributes, and Angular receives a truncated expression.
Root cause
packages/wp/wp/App/Oxygen/Functions.php, elegant_custom_fonts() (hooked to ct_builder_ng_init, priority 1000001):
$output = \wp_json_encode( $customCoreFontFamilies );
// ...
// The value is JSON-encoded specifically for this Oxygen JavaScript hook.
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo \sprintf( 'elegantCustomFonts=%s;', $output );
1.10.4 had the necessary escaping and worked:
$output = \htmlspecialchars( $output, \ENT_QUOTES );
echo \sprintf( 'elegantCustomFonts=%s;', $output );
The phpcs:ignore note treats the JSON as safe, but the destination is an HTML attribute — the JSON's own quotes still need htmlspecialchars. (Oxygen's core ct_init_elegant_custom_fonts() does htmlspecialchars( json_encode( ... ), ENT_QUOTES ) for exactly this reason.) Current main still has the unescaped echo.
Note the bug is invisible when the preset has no fonts ([] contains no quotes), which may be why it slipped through testing.
Suggested fix
Restore the escaping before the echo in elegant_custom_fonts():
$output = \htmlspecialchars( $output, \ENT_QUOTES );
Core Framework version or commit
2.0.1 (also present on current main)
Workaround we run in production meanwhile
An mu-plugin that wraps priority 1000001 of ct_builder_ng_init in an output buffer and applies htmlspecialchars( $chunk, ENT_QUOTES ) when the captured chunk contains raw quotes.
Summary
Since the 2.0 rewrite, opening any page in the Oxygen Builder never finishes loading — the loading screen stays up forever. Root cause:
elegant_custom_fonts()now echoes the font list into Oxygen'sct_builder_ng_inithook without HTML-escaping it, and that hook renders inside the double-quotedng-initHTML attribute of the builder template. The first raw"from the JSON terminates the attribute mid-expression.Affected surface
Oxygen (WordPress plugin)
Steps to reproduce
Expected behavior
Builder loads;
elegantCustomFontsis populated with the preset fonts (as in 1.10.4).Actual behavior
Builder hangs on the loading screen forever. Browser console shows AngularJS
Error: [$parse:ueoe](unexpected end of expression) for the builder'sng-initexpression, which ends abruptly at...init();elegantCustomFonts=[.The served HTML contains raw quotes inside the double-quoted attribute:
so the attribute closes after
[, the rest becomes garbage attributes, and Angular receives a truncated expression.Root cause
packages/wp/wp/App/Oxygen/Functions.php,elegant_custom_fonts()(hooked toct_builder_ng_init, priority 1000001):1.10.4 had the necessary escaping and worked:
The
phpcs:ignorenote treats the JSON as safe, but the destination is an HTML attribute — the JSON's own quotes still needhtmlspecialchars. (Oxygen's corect_init_elegant_custom_fonts()doeshtmlspecialchars( json_encode( ... ), ENT_QUOTES )for exactly this reason.) Currentmainstill has the unescaped echo.Note the bug is invisible when the preset has no fonts (
[]contains no quotes), which may be why it slipped through testing.Suggested fix
Restore the escaping before the echo in
elegant_custom_fonts():Core Framework version or commit
2.0.1 (also present on current
main)Workaround we run in production meanwhile
An mu-plugin that wraps priority 1000001 of
ct_builder_ng_initin an output buffer and applieshtmlspecialchars( $chunk, ENT_QUOTES )when the captured chunk contains raw quotes.