fix(fonts): preserve source stylesheet on Google Fonts cap overflow - #839
Merged
chubes4 merged 4 commits intoAug 5, 2026
Merged
Conversation
Replace hard-fail with tagged-union return for resolve_google_font_faces() and embed_font_sources(). On cap violation, emit assets/css/embedded-fonts.css with original Google @import, surface font_materialization_partial_preserved diagnostic with observed_bytes, limit_bytes, and url. Producer path unchanged. Fixes Automattic#732
The file was accidentally included in the fix commit. Restoring main's original version per request.
- widen return union with optional aggregate_bytes?:int on resolve_google_font_faces + embed_font_sources - drop always-true is_array/isset guards and impossible is_string branch in prepare_overlay - remove : array on smoke closures that return WP_Error Refs Automattic#839
Contributor
Author
CI Fix Summary — Homeboy Lint resolved
Smoke tests: both passing · phpcbf clean · CI re-run triggered. |
Inline embedded_fonts_css assignment now that state union guarantees 'embedded' after the preserved branch returns. Errors fixed: - phpstan.identical.alwaysTrue: 'embedded' === 'embedded' always evaluates to true at level 7 PHP 8.2 compatible. All CI checks passing. Refs Automattic#839
faisalahammad
commented
Aug 5, 2026
faisalahammad
left a comment
Contributor
Author
There was a problem hiding this comment.
CI Fix Summary — 1 failure resolved
| # | File | Error | Fix |
|---|---|---|---|
| 1 | includes/class-static-site-importer-font-materializer.php:125 | phpstan.identical.alwaysTrue | dropped dead if ( 'embedded' === $font_faces['state'] ); state union guarantees embedded after the preserved branch returns |
Tests ✅ · Verification ✅ · CodeRabbit ✅ (not part of CI gate; not run) · PHP 8.2 ✅
Refs #839
Contributor
Author
|
CI Fix Summary - 1 failure resolved
Tests passing. Verification clean. Homeboy Lint re-run 31038257340 passed 3m19s. PHP 8.1-8.4 all pass. Refs #839 |
Collaborator
|
Thanks @faisalahammad ! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A valid compiler font plan that exceeded SSI's fixed Google Fonts byte caps (CSS > 256 KiB or aggregate woff2 > 4 MiB) used to hard-abort the entire import with
static_site_importer_font_materialization_failed. The cap overflow now falls back to a preserved@importof the original Google stylesheet so the import continues, with afont_materialization_partial_preserveddiagnostic that reports the exact reason, observed bytes, and offending URL.Fixes #732
Changes
includes/class-static-site-importer-font-materializer.phpWhy: Multilingual fixtures (e.g.
29-multilingual-i18n) blow past the CSS or aggregate woff2 cap. The cap should be bounded, but exceeding it must not abort an otherwise valid import. The producer path (materialize_producer_faces) is unchanged.The two private helpers that materialize the Google Fonts path now return a tagged union instead of a bare CSS string.
prepare_overlay()inspects the union, and on apreservedstate re-scans the plan stylesheets for the original Google@importURL, writes an@import-onlyassets/css/embedded-fonts.css, and emits the diagnostic.Why: Strict allowlist
is_google_stylesheet_url()already gates the URL before it reaches CSS, but a defense-in-depthaddcslashes( $x, "\"\\\\\\n" )is applied to the URL interpolated into the@importstring so future allowlist loosening cannot leak a quote/backslash/newline into a CSS at-rule.tests/smoke-google-fonts-cap-fallback.php(new)Standalone PHP smoke, 5 cases:
@importof original URL,google_fonts_stylesheet_preserved_due_to_sizediagnostic withobserved_bytesandlimit_bytes === 262144.@import,google_fonts_payloads_partial_preserveddiagnostic withlimit_bytes === 4194304andaggregate_bytes.FontMaterializationPlanBuilderplan still materializes; required producer diagnostics still gate materialization.@importin plan + no fallback URL →WP_Errorclosed-fail withstylesheet_import_missingreason./css?family=…v1 URL — same preservation contract.test-manifest.json,homeboy-test-manifest.jsonRegistered the new smoke as
standalone-php.Testing
Test 1: standalone smokes
Result: both pass.
Test 2: fast lane + inventory
npm test npm run test:inventoryResult: 46/47 pass. The single failure is
smoke-url-batch-import.php(pre-existing on clean main, unrelated to fonts).Test 3: end-to-end repro against fixture
29-multilingual-i18nRun the fixture matrix; confirm the output no longer contains
static_site_importer_font_materialization_failedand that afont_materialization_partial_preserveddiagnostic appears withdetails.url,details.observed_bytes, anddetails.limit_bytespopulated. Browser surfaces (Chrome/SVG parity) should render text using the Noto Sans JP / Noto Naskh Arabic families.Test 4: happy path regression
Run a small Google Fonts fixture (1 family, 1 weight).
assets/css/embedded-fonts.cssshould still containdata:font/woff2;base64,…URLs and nofont_materialization_partial_preserveddiagnostic should appear.