Skip to content

Editor: Remove theme.json preset items of unexpected types to prevent fatals in PHP - #14262

Closed
ramonjd wants to merge 1 commit into
WordPress:trunkfrom
ramonjd:fix/theme-json-preset-item-types
Closed

ramonjd wants to merge 1 commit into
WordPress:trunkfrom
ramonjd:fix/theme-json-preset-item-types

Conversation

@ramonjd

@ramonjd ramonjd commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Trac ticket: https://core.trac.wordpress.org/ticket/66304

Backports WordPress/gutenberg#84534

Follow-up to https://core.trac.wordpress.org/changeset/64309

What

Removes theme.json preset items that aren't objects, or whose slug isn't a scalar, in WP_Theme_JSON::sanitize().

Why

Preset leaves are untyped in VALID_SETTINGS, so these items reach code that reads $preset['slug'] as a string. On trunk they throw a fatal TypeError:

  • A preset list of strings, such as "fontFamilies": [ "Inter" ], fails with Cannot access offset of type string on string when the stylesheet is generated.
  • A preset with an array slug fails in preg_match_all().
  • A palette keyed by origin with a string item, saved through the kses filter, fails in remove_insecure_settings().

What changed

  • sanitize() drops those items from plain preset lists and from lists keyed by origin, at the top level and per block. The filter lives in sanitize() rather than the constructor because remove_insecure_properties() (the kses save path) calls sanitize() but never constructs a WP_Theme_JSON.
  • Scalar slugs are kept, so an integer slug still works.

Valid data is unaffected. The Gutenberg PR also changes get_base_custom_css(), which only exists in the plugin, so there's nothing to port for it.

Each case has a test. All seven new cases fail on trunk.

@github-actions

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props ramonopoly.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Null preset entries and null slugs can bypass the new validation.

1 open finding
What changed in this PR

Sanitizes malformed theme.json preset entries to prevent stylesheet-generation failures.

Changes:

  • Filters non-array presets and non-scalar slugs.
  • Covers root, block, and origin-keyed presets.
  • Adds regression tests for sanitization and KSES paths.
File Description
src/​wp-includes/​class-wp-theme-json.php Filters malformed preset entries during sanitization.
tests/​phpunit/​tests/​theme/​wpThemeJson.php Adds malformed-preset regression coverage.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/wp-includes/class-wp-theme-json.php
@ramonjd ramonjd changed the title Editor: Remove theme.json preset items of unexpected types Editor: Remove theme.json preset items of unexpected types to prevent fatals in PHP Oct 14, 2026
@ramonjd ramonjd self-assigned this Oct 14, 2026
Preset leaves are untyped in `VALID_SETTINGS`, so a preset item that isn't an array, or whose `slug` isn't a scalar, reached code that reads `$preset['slug']` as a string and threw a fatal `TypeError`. `WP_Theme_JSON::sanitize()` now removes those items from plain preset lists and from lists keyed by origin, at the top level and per block. Filtering in `sanitize()` also covers `remove_insecure_properties()`, which the kses filter uses when global styles are saved.

Scalar slugs are kept, so an integer `slug` still works.

Backports WordPress/gutenberg#84534.

See #66304.
@ramonjd
ramonjd force-pushed the fix/theme-json-preset-item-types branch from cfb3563 to 556b753 Compare October 18, 2026 21:43

@tellthemachines tellthemachines left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes are consistent with WordPress/gutenberg#84534; LGTM!

wporg-sync pushed a commit that referenced this pull request Oct 18, 2026
… fatals in PHP

This commit prevents `WP_Theme_JSON` from throwing fatal TypeErrors when preset items in theme.json or global styles data contain values of the wrong type. Those values could be user- or AI-generated.

It does this by removing theme.json preset items that aren't objects, or whose `slug` isn't a scalar, in `WP_Theme_JSON::sanitize()`.

Previouly, for example, a preset list of strings, such as `"fontFamilies": [ "Inter" ]`, failed with `Cannot access offset of type string on string` when the stylesheet is generated.

Developed in: #14262

Props ramonopoly, aaronrobertshaw, isabel_brison.

Fixes #66304.



git-svn-id: https://develop.svn.wordpress.org/trunk@64491 602fd350-edb4-49c9-b593-d223f7449a82
@github-actions

Copy link
Copy Markdown

A commit was made that fixes the Trac ticket referenced in the description of this pull request.

SVN changeset: 64491
GitHub commit: 4f9f74c

This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.

@github-actions github-actions Bot closed this Oct 18, 2026
wporg-sync pushed a commit to WordPress/WordPress that referenced this pull request Oct 18, 2026
… fatals in PHP

This commit prevents `WP_Theme_JSON` from throwing fatal TypeErrors when preset items in theme.json or global styles data contain values of the wrong type. Those values could be user- or AI-generated.

It does this by removing theme.json preset items that aren't objects, or whose `slug` isn't a scalar, in `WP_Theme_JSON::sanitize()`.

Previouly, for example, a preset list of strings, such as `"fontFamilies": [ "Inter" ]`, failed with `Cannot access offset of type string on string` when the stylesheet is generated.

Developed in: WordPress/wordpress-develop#14262

Props ramonopoly, aaronrobertshaw, isabel_brison.

Fixes #66304.


Built from https://develop.svn.wordpress.org/trunk@64491


git-svn-id: http://core.svn.wordpress.org/trunk@63641 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants