Skip to content

fix!: preserve patterns' namespaced names and sanitize scripts - #188

Merged
justlevine merged 1 commit into
fix/utilsfrom
fix/sanitize-namespaces
Oct 26, 2026
Merged

justlevine merged 1 commit into
fix/utilsfrom
fix/sanitize-namespaces

Conversation

@justlevine

@justlevine justlevine commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

What

Brand sites keep the namespaced names of the patterns they receive, and strip scripts from them. The governing site sanitizes the patterns brand sites send back the same way.

Why

  • receive_patterns() ran the name through sanitize_key(), so a shared theme/hero was stored and registered as themehero.
  • It stored the content as it came, scripts and event handlers included.
  • get_all_brand_site_patterns() passed on whatever each brand site listed without sanitizing it.

Related Issue(s):

How

  • PATTERN_SCHEMA lists the fields a brand site registers a pattern with.
  • sanitize_pattern() keeps only those fields, each sanitized. The content goes through wp_kses_post(), and the name through sanitize_text_field(), which keeps the slash.
  • /receive-patterns stores each pattern under its sanitized name, which is the name the brand site registers it with.
  • /get-all-brand-site-patterns skips a pattern that doesn't match PATTERN_SCHEMA and sanitizes the rest.
  • Adds PHPUnit tests for both directions, and a set_up_brand_site() helper on TestCase.

AI Disclosure

Claude Code identified the issue, wrote the tests the tests, and drafted the PR description.

Testing Instructions

Screenshots

Additional Info

This is no migration for the old sanitized names before this PR. Uninstall/reinstall is the current migration path.

Checklist

  • I have read the Contribution Guidelines.
  • I have read the Development Guidelines.
  • I have added necessary tests to cover my changes.
  • I have updated the project documentation as needed.
  • My code has detailed inline documentation.
  • My code is tested to the best of my abilities.
  • My code passes all lints, tests, and checks.
Open WordPress Playground Preview

@justlevine
justlevine merged commit 615cf79 into main Oct 26, 2026
18 checks passed
@justlevine
justlevine deleted the fix/sanitize-namespaces branch October 26, 2026 09:52

return array_filter(
[
'name' => sanitize_text_field( (string) $pattern['name'] ),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@justlevine Edge case: if both sites have a pattern with the same name but different versions, the pushed version is silently ignored. register_block_patterns_if_not_exist() skips names that are already registered.

thoughts?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@Kallyan01 this is preexisting, right?

I'm unsure what the expected behavior would be: always the pushed version, the latest version of them? 🤔

Create a new GH issue in /onepress for tracking.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@justlevine ig no. Previously, the slash was omitted from the pushed pattern names, which caused them to be registered under different names without any additional changes.

What about de-registering any existing pattern before we register the new one, so the pushed one gets priority or making them co-exist together?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

How would dropping the prefix cause fewer conflicts instead of more conflicts?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@justlevine if I'm not wrong, it isn't really dropping the prefix. it only removes the slash, so the namespace text became twentytwentyfivebanner-about-book. That's no longer a namespaced name, so it can never match a pattern the brand site registers itself. The shared copy was registered next to the local one instead of competing with it.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I genuinely don't understand what you're trying to say here....

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Per sync w. @up1512001 :

Short term: follow Templates (skip pattern if already registered) + array_map( explode '/' ... ) ... )
Long term: show notice on governing site. Needs issue.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@justlevine Okay, if we're intentionally skipping registration, the current logic makes sense for now. However, adding a notice would make the behavior more user-friendly, as users might otherwise be unaware of why the registration failed.

Screen.Recording.2026-10-28.at.21.53.37.mov

[
'name' => sanitize_text_field( (string) $pattern['name'] ),
'title' => sanitize_text_field( (string) $pattern['title'] ),
'content' => wp_kses_post( (string) $pattern['content'] ),

@Kallyan01 Kallyan01 Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@justlevine wp_kses_post strips inline SVGs, which breaks the rt-carousel arrows in the Vertex patterns case-study-carousel, featured-case-studies, feature-stats-with-testimonial and testimonials-carousel. I think switching to wp_kses with the post allowlist plus SVG shape tags only, leaving out the XSS-prone parts (, , animation tags, on* handlers). Thoughts?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@Kallyan01 IMO this feels like a bug in rt-carousel. If it's using SVGs, then shouldn't it use set wp_kses_allowed_html filter to allow them?

Check with rt-carousel, and we'll make a decision based on what they say.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

rt-carousel fix PR: rtCamp/rt-carousel#219

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants