This was brought up during fuzz testing of the HTML API. After
polyfilling `mb_chr()` and relying on it in the HTML decoder, it became
possible that for sites with a non-UTF-8 charset selected, then the
creation of text from code points when decoding numeric character
references might produce corrupted text, or text which encodes to
non-UTF-8 bytes.
While for these sites, there are broader issues with non-UTF-8 support,
this change ensures that code point encoding remains deterministic.
Developed in: https://github.com/WordPress/wordpress-develop/pull/12155
Discussed in: https://core.trac.wordpress.org/ticket/65372
Follow-up to [62424].
Props dmsnell, jonsurrell.
See #65372.
Built from https://develop.svn.wordpress.org/trunk@62487
git-svn-id: http://core.svn.wordpress.org/trunk@61768 1a063a9b-81f0-0310-95a4-ce76da25c4cd
The `wow-actions/welcome` action has not been updated for over 2 years and is currently configured to run on `Node20`. With GitHub now actively removing support for Node.js 20.x within the GitHub Actions environment, any action explicitly using `Node20` will break.
This replaces `wow-actions/welcome` with the `actions/first-interaction` action, which is an action officially maintained by GitHub and offers the same functionality.
Props khokansardar, mukesh27, desrosj.
Fixes#65432.
Built from https://develop.svn.wordpress.org/trunk@62486
git-svn-id: http://core.svn.wordpress.org/trunk@61767 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Found during fuzzing work on the HTML API and adjacent code. The previous version of this function used a Unicode PCRE to detect noncharacter code points, but that invocation failed if the input string contained sequences of invalid UTF-8 bytes.
This patch replaces the Unicode PCRE with a mapped sequence of raw bytes. This version works in environments without Unicode support and it works when invalid bytes are present, making it possible to remove the fallback function as well.
Developed in: https://github.com/WordPress/wordpress-develop/pull/12148
Discussed in: https://core.trac.wordpress.org/ticket/65372
Follow-up to [61000].
Props dmsnell, jonsurrell.
See #65372.
Built from https://develop.svn.wordpress.org/trunk@62485
git-svn-id: http://core.svn.wordpress.org/trunk@61766 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This adds support for the unicode address extensions in RFC 6530-3 and refactors the code so there are fewer long regexes and less duplication between sanitize_email and is_email. A new class, WP_Email_Address, provides the shared parts.
Opting out of unicode support is easy, default-filters.php adds unicode support by adding filters, which can be removed.
`sanitize_email` no longer does major changes like removing an entire subdomain from someone's address, it only cleans up things like soft hyphens and whitespace — changes that happen when coping an email address from text.
Developed in: https://github.com/WordPress/wordpress-develop/pull/5237
Discussed in: https://core.trac.wordpress.org/ticket/31992
Props agulbra, akirk, benniledl, dmsnell, ironprogrammer, justlevine, mdawaffe, mukeshpanchal27, SirLouen, tusharbharti.
Fixes#31992.
Built from https://develop.svn.wordpress.org/trunk@62482
git-svn-id: http://core.svn.wordpress.org/trunk@61763 1a063a9b-81f0-0310-95a4-ce76da25c4cd
The image editor help toggle icon used a hardcoded classic blue color. Replace it with a CSS custom property so the icon follows the user's admin color scheme.
Props dervishov, huzaifaalmesbah, jamesbregenzer, mukesh27, ozgursar, wildworks.
Fixes#64937.
Built from https://develop.svn.wordpress.org/trunk@62481
git-svn-id: http://core.svn.wordpress.org/trunk@61762 1a063a9b-81f0-0310-95a4-ce76da25c4cd
The spinner that appeared during filtering was positioned beneath the fields, causing a scrollbar in the filter wrapper container. While only visible during scrolling on MacOS, it was persistently visible on Windows.
Fixes the alignment of the toolbar to appear with predictable alignment to the select fields without generating a scrollbar.
Follow up to [61757].
Props luismulinari, yogeshbhutkar, dhruvang21, r1k0, sabernhardt, wildworks, audrasjb, joedolson.
Fixes#65275. See #23562.
Built from https://develop.svn.wordpress.org/trunk@62480
git-svn-id: http://core.svn.wordpress.org/trunk@61761 1a063a9b-81f0-0310-95a4-ce76da25c4cd
The `@deprecated` tags for the legacy `contextual_help_list`, `contextual_help`, and `default_contextual_help` filters pointed to `{@see get_current_screen()->add_help_tab()}` and `{@see get_current_screen()->remove_help_tab()}`. These method-call chains are not resolvable references, so they rendered as broken links on the Developer Reference site (and in IDEs such as PhpStorm). Replace them with references that resolve: `get_current_screen()`, `WP_Screen::add_help_tab()`, and `WP_Screen::remove_help_tab()`.
Developed in https://github.com/WordPress/wordpress-develop/pull/12071.
Follow-up to r46685.
Props ekamran, yusufmudagal, dhruvang21, codesmith32.
Fixes#65401.
Built from https://develop.svn.wordpress.org/trunk@62477
git-svn-id: http://core.svn.wordpress.org/trunk@61758 1a063a9b-81f0-0310-95a4-ce76da25c4cd
The documented return type is `WP_Term|WP_Post_Type|WP_Post|WP_User|null`, but `get_queried_object()` could return `false` from author queries because `get_userdata()` yields `false` when the resolved author ID is `null` or matches no user. Guard the `get_userdata()` call and its result so `$this->queried_object` stays `null` in those cases. The adjacent posts page branch is hardened the same way, since `get_post()` can return `null` for a missing or deleted page, which previously caused a property access on `null`.
Developed in https://github.com/WordPress/wordpress-develop/pull/12069.
Follow-up to r52822, r3290.
Props tusharbharti, tommusrhodus, yusufmudagal, westonruter.
Fixes#65400.
Built from https://develop.svn.wordpress.org/trunk@62476
git-svn-id: http://core.svn.wordpress.org/trunk@61757 1a063a9b-81f0-0310-95a4-ce76da25c4cd
The `wp_render_elements_class_name()` function reads the `className` block attribute and passes it straight to `preg_match()`. While `className` is expected to be a string, malformed or corrupted stored block data can hold another type, such as an array, which triggers a fatal `TypeError` on PHP 8+. Guard against this by returning the block content unchanged when `className` is not a string.
While here, align the implementation with `wp_render_custom_css_class_name()` from r62359: replace the regular expression with a `str_contains()` short-circuit followed by an HTML-spec-compliant `strtok()` walk over the class tokens. This also corrects a latent matching bug: the previous `\bwp-elements-\S+\b` pattern treated the hyphen as a word boundary, so a class such as `my-wp-elements-foo` was erroneously matched. Tokenizing the attribute first ensures only a standalone `wp-elements-*` class is applied.
Add regression tests for the non-string and substring-prefix cases, and resolve PHPStan errors at rule level 10 (`missingType.iterableValue`, `offsetAccess.nonOffsetAccessible`, `argument.type`) by adding an array shape to the `@phpstan-param` tag.
Developed in https://github.com/WordPress/wordpress-develop/pull/12028 and https://github.com/WordPress/gutenberg/pull/78841.
Follow-up to r58074, r62359.
Props aaronrobertshaw, andrewserong, mukesh27, westonruter.
Fixes#65379.
Built from https://develop.svn.wordpress.org/trunk@62475
git-svn-id: http://core.svn.wordpress.org/trunk@61756 1a063a9b-81f0-0310-95a4-ce76da25c4cd
The previous `round( (float) $maybe_integer ) === (float) $maybe_integer` check rejected large integers on PHP 8.4. The check itself was fragile: a PHP `float` (a 64-bit IEEE-754 double) can represent every integer exactly only up to 2^53, so casting larger values is lossy. Nevertheless, that lossiness alone did not reject anything, since both sides of the comparison were munged identically. What actually broke it was a `round()` regression in PHP 8.4, where `round( (float) $x )` can return a value different from `(float) $x` for certain numbers. That inequality caused canonical integers still valid for a `BIGINT UNSIGNED` column (such as unusually high post IDs) to be incorrectly rejected by REST validation, only on PHP 8.4+.
The function now short-circuits returning true for native integers and canonical integer strings so that integer-like values of any magnitude are detected correctly. Decimal and scientific-notation strings (and floats) retain their historical behavior, including the existing float comparison, now rewritten as a `floor()` check whose strict equality compares a float to its own floor and is therefore exact. The limitations around `PHP_INT_MAX` and fractional magnitudes beyond `2 ** 53` are documented on the function, and the data provider gains coverage for large integers, negative floats, and scientific notation.
Developed in https://github.com/WordPress/wordpress-develop/pull/11893.
Follow-up to r48306.
Props siliconforks, gautam23, westonruter, kevinfodness, mboynes, desrosj.
Fixes#65271.
Built from https://develop.svn.wordpress.org/trunk@62474
git-svn-id: http://core.svn.wordpress.org/trunk@61755 1a063a9b-81f0-0310-95a4-ce76da25c4cd
The throttled `input` handler in `wp.media.view.MediaFrame.Manage` only called `gridRouter.navigate()` when the search value was non-empty, so emptying the search box left the `?search=` query parameter in the address bar. Reloading the page then re-parsed that stale parameter and refilled the input. So now the `navigate()` method is called unconditionally when the input changes in order to reset the URL back to the base `upload.php`.
Developed in https://github.com/WordPress/wordpress-develop/pull/11938.
Follow-up to r41021.
Props mohamedahamed, abduremon, jorbin, ekla, drwpcom, anukasha, huzaifaalmesbah, noruzzaman, rejaulalomkhan, hmbashar, nadabulija, robert681, pedrofigueroa1989, westonruter.
Fixes#65298.
Built from https://develop.svn.wordpress.org/trunk@62470
git-svn-id: http://core.svn.wordpress.org/trunk@61751 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Avoid layout element shift by setting position attributes on `.media-bg-overlay` in all viewports, avoiding redraw of flex layout.
Props abduremon, mohamedahamed, wildworks, khokansardar, darshitrajyaguru97, joedolson.
Fixes#65296.
Built from https://develop.svn.wordpress.org/trunk@62469
git-svn-id: http://core.svn.wordpress.org/trunk@61750 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This changeset replaces recently introduced `false !== strpos( ... )` and `false === strpos( ... )` with `str_contains()` in core files, making the code more readable and consistent, as well as better aligned with modern development practices.
Introduced in [60269] and [60939]. Fixed during WCEU2026 contribution day.
Follow-up to [52039], [55988], [56245], [60269] and [60939].
Props Soean, mukesh27.
Fixes#65408.
Built from https://develop.svn.wordpress.org/trunk@62461
git-svn-id: http://core.svn.wordpress.org/trunk@61742 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Make the focus outline transparent to avoid showing an unnatural focus outline on the front end. In Windows high contrast mode, the focus outline is still displayed as before.
Props hbhalodia, joedolson, wildworks.
Fixes#65177.
Built from https://develop.svn.wordpress.org/trunk@62459
git-svn-id: http://core.svn.wordpress.org/trunk@61740 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Some Emoji characters have a default text presentation defined in the Unicode specification. However, some of these characters (mainly ↗ ↘ ↙ ↖) are incorrectly being converted to an emoji character instead due to a bug in the Twemoji library.
Version `17.0.3` fixes this bug and ↗ ↘ ↙ ↖ characters are now presented as intended.
A full list of changes in this release can be found on GitHub: https://github.com/jdecked/twemoji/compare/v17.0.2...v17.0.3.
Because there are no visual modifications to the image assets, a new folder has not been pushed to the WordPress.org CDN and core will continue to reference `/images/core/emoji/17.0.2` to avoid needlessly busting caches.
Props jdecked, joen, westonruter, peterwilsoncc, jorbin, siliconforks, desrosj, presskopp, wildworks, audrasjb, iflairwebtechnologies.
Fixes#64318.
Built from https://develop.svn.wordpress.org/trunk@62457
git-svn-id: http://core.svn.wordpress.org/trunk@61738 1a063a9b-81f0-0310-95a4-ce76da25c4cd
* Note that the `gallery_style` filter receives the opening HTML `DIV` container in addition to the default CSS.
* Point to the `use_default_gallery_style` filter as the way to remove the styles entirely.
* Add the missing `@since` changelog entries describing how the filtered markup has evolved.
Developed in https://github.com/WordPress/wordpress-develop/pull/12060.
Follow-up to r16865, r27396, r46164, r61411.
Props sabernhardt, ov3rfly, westonruter.
See #64442.
Fixes#65317.
Built from https://develop.svn.wordpress.org/trunk@62455
git-svn-id: http://core.svn.wordpress.org/trunk@61736 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Update the core admin color schemes so their sidebar and primary button colors
work well when the block editor and Site Editor apply the user's admin color
scheme to the editor chrome. The chrome background is generated from a seed
through the WPDS ramp algorithm, which only emits surface colors within
specific luminance bands and cannot reproduce arbitrary colors, so several
schemes could never match.
Adjust the Blue, Coffee, Ectoplasm, Light, Midnight, Ocean, and Sunrise schemes
to bring sidebar and primary button text contrast to WCAG 2.x AA (4.5:1), keep
each scheme's character, and reduce the number of distinct colors per scheme by
reusing the selected menu item's background for the primary button (except for
Light).
Props fushar, simison, youknowriad, joen.
Fixes#65382.
Built from https://develop.svn.wordpress.org/trunk@62454
git-svn-id: http://core.svn.wordpress.org/trunk@61735 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Three of the four `_doing_it_wrong()` calls in `WP_Block_Type_Registry::register()` emitted a generic message that did not identify which block name triggered it, making it hard to locate the offending registration. The notices for non-string names, uppercase characters, and a missing namespace prefix now include the received value (the type via `gettype()` for non-strings, and the escaped name otherwise), matching the existing "already registered" notice that did already report the name.
Developed in https://github.com/WordPress/wordpress-develop/pull/11478.
Follow-up to r44108.
Props manishxdp, desrosj, benjgrolleau, westonruter.
Fixes#65039.
Built from https://develop.svn.wordpress.org/trunk@62452
git-svn-id: http://core.svn.wordpress.org/trunk@61733 1a063a9b-81f0-0310-95a4-ce76da25c4cd
The string `"0"` and the integer `0` were previously dropped when merging block wrapper attributes because falsy values were filtered out. Strings and numbers are now kept and cast to a string, so zero values are preserved.
Type annotations and null checks are also improved.
Props westonruter, wildworks.
Fixes#64452.
Built from https://develop.svn.wordpress.org/trunk@62450
git-svn-id: http://core.svn.wordpress.org/trunk@61731 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Ability schemas are a public contract that REST clients, including the `@wordpress/abilities` JavaScript client, validate against as standard JSON Schema. The `required` keyword must therefore use the draft-04 array-of-property-names form, not the draft-03 per-property boolean that `rest_validate_value_from_schema()` also accepts on the server.
In `WP_REST_Abilities_V1_List_Controller::prepare_schema_for_response()`, collect per-property `required: true` booleans into a parent `required` array, recursively and inside array `items`. Strip `required: false` and boolean `required` values with no draft-04 equivalent, and honor `rest_validate_object_value_from_schema()` precedence where an existing draft-04 array wins. Only the REST response copy is rewritten; stored schemas and server-side validation are unchanged.
Props gziolo, westonruter, jorgefilipecosta.
See #64955.
Built from https://develop.svn.wordpress.org/trunk@62449
git-svn-id: http://core.svn.wordpress.org/trunk@61730 1a063a9b-81f0-0310-95a4-ce76da25c4cd
The plugin search form does not apply to the Favorites tab, which instead expects a WordPress.org username to look up a user's favorited plugins. Rendering the term-based search form there was misleading. Update `WP_Plugin_Install_List_Table::views()` to read the global `$tab` and skip `install_search_form()` when the favorites tab is active, while leaving the form in place on the Featured, Popular, and Recommended tabs.
Developed in https://github.com/WordPress/wordpress-develop/pull/11457.
Props manishxdp, bor0, westonruter, shailu25, sabbir1991.
Fixes#65026.
Built from https://develop.svn.wordpress.org/trunk@62448
git-svn-id: http://core.svn.wordpress.org/trunk@61729 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Switch the Abilities REST API schema response preparation from an internal-keyword deny-list to an allow-list, so ability input and output schemas expose only keywords from `rest_get_allowed_schema_keywords()\` plus a small set of additional draft-04 keywords. Unknown or WordPress-internal keywords (e.g. `sanitize_callback`, `example`, `context`, `readonly`) are no longer exposed to REST clients by default.
Props gziolo, jorgefilipecosta.
See #64955.
Built from https://develop.svn.wordpress.org/trunk@62447
git-svn-id: http://core.svn.wordpress.org/trunk@61728 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Add a data-provider-driven test documenting that a `required` flag at the root of a schema is never consulted by `WP_Ability::validate_input()`:
* top-level `required: true`/`false` is inert; only `type` is enforced, and `false` does not permit `null`.
* a draft-04 `required` array on an object type is honored and enforces property presence.
Also remove the inert top-level `required => true` flags from simple-type test schemas, keeping the meaningful per-property flags. Test-only change.
Follow-up [61032], #64098.
See #64955.
Built from https://develop.svn.wordpress.org/trunk@62441
git-svn-id: http://core.svn.wordpress.org/trunk@61722 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Add characterization tests documenting that an ability ignores two REST-style schema keywords:
* `validate_callback` is never invoked. The REST request layer calls it, but `rest_validate_value_from_schema()` does not.
* There is no sanitization pass, so `sanitize_callback` never runs and input reaches the execute callback uncoerced.
Custom validation belongs in the `wp_ability_validate_input` / `wp_ability_validate_output` filters. Test-only change.
`arg_options` is intentionally not covered here: it is a registration-time helper for `rest_get_endpoint_args_for_schema()` with no runtime meaning for abilities.
Follow-up [61032], #64098.
See #64955.
Built from https://develop.svn.wordpress.org/trunk@62440
git-svn-id: http://core.svn.wordpress.org/trunk@61721 1a063a9b-81f0-0310-95a4-ce76da25c4cd