Repository navigation
Conversation
…tes` filter. `wp_get_inline_script_tag()` passed the raw data to the filter and then set the text with `WP_HTML_Tag_Processor::set_modifiable_text()`, which escapes `<script` and `</script` in JavaScript and JSON, so a callback deriving an attribute from the text, such as a CSP hash, could compute it from text that was not printed. The function now builds the tag from the caller's attributes first, passes the text as the browser parses it from the printed tag, and builds the tag again when the filter changes the attributes, because the `type` and `language` attributes decide how the text is escaped. See #66308.
Test using WordPress PlaygroundThe 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
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
|
This is a tricky problem because the resulting script tag contents depend on the If the filter is applied first, the filter function may be passed script data that isn't what's actually printed. But if the filter is applied after, then the attributes necessary for escaping may not have been applied so escaping may be applied incorrectly or not applied at all. I don't think the same problem applies to #13250 because the content type of |
|
This seems like a change in contract. Instead I think we should document the limitation and consider workarounds if it's essential that the filter see the exact contents that will be printed in the script tag. |
wp_get_inline_script_tag()passed$datato thewp_inline_script_attributesfilter and then set it as the SCRIPT text. Since r61477,set_modifiable_text()escapes<scriptand</scriptin JavaScript and JSON, so the printed text can differ from what the filter received. A callback that derives an attribute from the text, such as a CSP hash, produces a value that does not match the element, and the browser blocks the script.The filter now receives
get_modifiable_text(): the text as a browser parses it from the printed tag, with<scriptand</scriptescaped and CR and CRLF normalized to LF.The Tag Processor chooses the escaping from the
typeandlanguageattributes when the text is set, so the tag is built from the caller's attributes first, the filter runs on that text, and when the filter changes the attributes the tag is built again from the filtered array. Two consequences:''before.typeorlanguagebetween a recognized and an unrecognized content type changes the escaping of the printed text after the filter saw it. The filter docblock states this.Tests cover the escaped text, newline normalization, attribute replacement, and both failure paths.
Trac ticket: https://core.trac.wordpress.org/ticket/66308
Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Fable 5.1
Used for: Implementation, tests, review and description.
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.